🛰 Promise 的几个关键问题

1⃣️ 改变 Promise 的状态的三个方法:

  • resolve(value) :如果当前是 pending 就会变为 resolved;

  • reject(reason) :如果当前是 pending 就会变为 rejected;

  • 抛出异常: 如果当前是 pending 就会变为 rejected;

🌰 例子:

let p = new Promise((resolve, reject) => {
    resolve('ok');
});
//执行 then 方法的结果
let result = p.then(value => {
    // console.log(value);
    //1. 抛出错误
    // throw '出了问题';
    //2. 返回结果是非 Promise 类型的对象
    // return 521;
    //3. 返回结果是 Promise 对象
    return new Promise((resolve, reject) => {
        // resolve('success');
        reject('error');
    });
}, reason => {
    console.warn(reason);
});

console.log(result);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

2⃣️ 指定多个成功 / 失败回调函数,都会调用吗?

  • 当 Promise 改变为对应的状态时都会调用

🌰 例子:

let p = new Promise((resolve, reject) => {
    // resolve('OK'); // 先改变状态后运行回调
    setTimeout(()=>{
        resolve('OK')
    },1000)
});

///指定回调 - 1
p.then(value => {
    console.log(value);
});

//指定回调 - 2
/*p.then(value => {
    alert(value);
});*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

3⃣️ 改变 Promise 状态和指定回调函数的先后顺序

  • 都有可能。正常情况下是先指定回调函数再改变 Promise 的状态,但也可以先改状态再指定回调函数。
  • 先改状态再指定回调的情况:
    • 在执行其中直接调用 resolve() / reject()
    • 延迟更长时间才调用 then()
  • 什么时候才能得到数据:
    • 如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据;
    • 如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据;

(主要关注 Promise 构造时里面是同步或异步任务)

🌰 例子

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('OK');
    }, 1000);
});

p.then(value => {
    console.log(value);
},reason=>{
 		console.warn(reason)   
})
1
2
3
4
5
6
7
8
9
10
11

4⃣️ promise.then() 返回的新 Promise 的结果状态由什么决定?

  • 简单表达:由 then() 指定的回调函数执行的结果决定

  • 详细表达:

    • 如果抛出异常,新 Promise 变为 rejectedreason 为抛出的异常。
    • 如果返回的是非 Promise 的任意值,新 Promise 变为 resolvedvalue 为返回的值
    • 如果返回的是另一个新 Promise,此 Promise 的结果就会成为新 Promise 的结果。

🌰 例子:

let p = new Promise((resolve, reject) => {
    resolve('ok');
});
//执行 then 方法的结果
let result = p.then(value => {
    // console.log(value);
    //1. 抛出错误
    // throw '出了问题';
    //2. 返回结果是非 Promise 类型的对象
    // return 521;
    //3. 返回结果是 Promise 对象
    return new Promise((resolve, reject) => {
        // resolve('success');
        reject('error');
    });
}, reason => {
    console.warn(reason);
});

console.log(result);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

5⃣️ Promise 如何串连多个操作任务?

  • Promise 的 then() 返回一个新的 Promise,可以开成 then() 的链式调用
  • 通过 then 的链式调用串连多个同步 / 异步任务。

🌰 例子:

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('OK');
    }, 1000);
});

p.then(value => {
    return new Promise((resolve, reject) => {
        resolve("success");
    });
}).then(value => {
    console.log(value);
}).then(value => {
    console.log(value); // undefined 上一个 Promise无返回值
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

6⃣️ Promise 异常传透:

  • 当使用 Promise 的 then 链式调用时,可以在最后指定失败的回调
  • 前面任何操作出了异常都会传到最后失败的回调中处理

🌰 例子:

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('OK');
        // reject('Err');
    }, 1000);
});

p.then(value => {
    // console.log(111);
    throw '失败啦!';
}).then(value => {
    console.log(222);
}).then(value => {
    console.log(333);
}).catch(reason => {
    console.warn(reason);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

7⃣️ 中断 Promise 链:

  • 当使用 Promise 的 then 链式调用时,在中间中断,不再调用后面的回调函数

  • 办法:在回调函数中返回一个 pendding 状态的 Promise 对象。(有且只有一种方式)

🌰 例子:

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('OK');
    }, 1000);
});

p.then(value => {
    console.log(111);
    //有且只有一个方式
    return new Promise(() => {});
}).then(value => {
    console.log(222);
}).then(value => {
    console.log(333);
}).catch(reason => {
    console.warn(reason);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
📢 上次更新: 2022/09/02, 10:18:16