Promise的一些关键性问题

67 阅读2分钟

想使用好Promise,除了上篇文章讲的一些基础用法以外,还要知道Promise的一些关键性问题,接下来我们就来好好讲讲。

Promise的状态能被什么改变

Promise实例对象的状态很重要,它决定了后续怎么去处理这个异步操作。

Promise的状态只有三种方式可以改变:

调用resolve函数,使状态由pending转变为fulfilled

    let p = new Promise((resolve, reject) => {
      resolve("ok");
    });

调用reject函数,使状态由pending转变为rejected

    let p = new Promise((resolve, reject) => {
      reject("no ok");
    });

抛出错误,使状态由pending转变为rejected

    let p = new Promise((resolve, reject) => {
      throw "no ok";
    });

Promise能否调用多个回调函数

Promise实例对象可以指定多个回调函数,当Promise实例对象的状态改变以后,会根据状态进行调用回调函数,有几个回调函数就调用几个。

    let p = new Promise((resolve, reject) => {
      resolve("ok");
    });

    p.then(() => {
      console.log(1);
    });

    p.then(() => {
      console.log(2);
    });

1740413254103.png

then方法的返回结果由什么决定

前面说了,then方法和catch方法会返回一个新的Promise实例对象,这也是Promise能够链式调用的原因,现在我们就来看一下这个新的Promise实例对象由什么决定的。这里我们用then方法讨论。

    let p = new Promise((resolve, reject) => {
      resolve("ok");
    });

    let newP = p.then((res) => {});

then方法返回的新Prromise实例对象newPp.then(onResolved,onRejected)里是调用onResolved函数还是onRejected函数无关,跟函数的执行结果有关。

  • 回调函数抛出异常:newP的状态就是rejected,结果就是抛出去的异常。
  • 回调函数return一个非Promise实例对象:newP的状态就是fulfilled,结果就是return出去的值。
  • 回调函数不return,也不抛出异常:参考第二个,看成return出去一个undefinednewP的状态就是fulfilled,结果就是undefined
  • 回调函数return一个Promise实例对象:那么newP的状态和结果就和这个return出去的Promise实例对象相同。

这么看,then方法返回方式很像Promise.resolve()方法。

    let p = new Promise((resolve, reject) => {
      resolve("ok");
    });

    // 抛出异常
    let newP1 = p.then((res) => {
      throw "我错了";
    });
    console.log(newP1, "newP1");

    // return 非Promise实例对象
    let newP2 = p.then((res) => {
      return "我是非Promise实例对象";
    });
    console.log(newP2, "newP2");

    // 不return 也不抛出异常
    let newP3 = p.then((res) => {});
    console.log(newP3, "newP3");

    // return 一个Promise实例对象
    let newP4 = p.then((res) => {
      return Promise.reject("我是失败状态的实例对象");
    });
    console.log(newP4, "newP4");

1740488410859.png