1.一个 Promise 指定多个成功/失败回调函数, 都会调用吗?

  • 答案是肯定的,当 promise 改变为对应状态时都会调用

2.改变 promise 状态和指定回调函数谁先谁后?

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

3.Promise.then()返回的新 Promise 的结果状态由什么决定?

  • (1)简单表达: 由 then()指定的回调函数执行的结果决定
  • (2)详细表达:
    • ① 如果抛出异常, 新 promise 变为rejected, reason 为抛出的异常
    • ② 如果返回的是非 promise 的任意值, 新 promise 变为resolved, value 为返回的值
    • ③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果

4.Promise中的异常穿透特性

  • (1)当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调
  • (2)前面任何操作出了异常, 都会传到最后失败的回调中处理
    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);//可以在最后的catch环节捕获第一层的错误
    });

结果如下:

image

解释说明:

  • promise的链式调用中存在一种异常穿透的特性,就是我们可以在链式作用的最后加上一个catch方法来捕获整个链式调用过程中的错误,无需在链式调用的每一个环节参加catch方法来捕获错误

5.中断 Promise 的链式调用?

  • (1)当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数
  • (2)办法: 在回调函数中返回一个 pendding 状态的 promise 对象
    let p = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('OK');
    }, 1000);
    });

    p.then(value => {
    console.log(111);
    //有且只有一个方式:那就是返回一个pending状态的Promise对象,才能中断Promise1链条
    return new Promise(() => {});
    }).then(value => {
    console.log(222);
    }).then(value => {
    console.log(333);
    }).catch(reason => {
    console.warn(reason);
    });
    // 输出结果只有111,无222,333

结果如下:

image

解释说明:

  • 中断Promise链式调用的方法有且只有一种:那就是在你想要中断的环节当中添加一个pending状态的Promise对象返回值