Notes

Promise 的使用细节

使用方法 A

const promiseA = new Promise((fulfill, reject) => {
  fulfill('here');
});

promiseA.then((value) => {
  console.log(`${value} a`);
});

promiseA.then((value) => {
  console.log(`${value} b`);
});

使用方法 B

const promiseB = new Promise((fulfill, reject) => { fulfill('here'); })
                       .then((value) => { console.log(`${value} a`); })
                       .then((value) => { console.log(`${value} b`); });

使用 Promise 时,可以使用以上两种的形式进行调用

方法 A 和方法 B 看上去做的事情都是一样,都是根据等新建出来的 Promise 中的异步过程完成后,继续后面的工作,但实际上,这两种方法的执行机制是不同的

方法 A 的输出

here a
here b

方法 B 的输出

here a
undefined b

工作原理

当我们新建一个 Promise 对象 p 后,p 中实际上是有两个数组来保存回调的方法,两个数组分别保存异步操作成功后的回调,异步操作失败后的回调

而当在 p 上调用 then 方法时,成功回调和失败回调就会分别保存到对应的数组上,或者说是一个队列上。同时,then 方法的调用结果是返回一个新的 Promise 对象。没错,一个新的 Promise 对象,是与 p 完全不一样的对象,这是规范中写明的

因此,对于使用方法 A

而,对于使用方法 B

实际效果等同于

const promiseB = new Promise((fulfill, reject) => { fulfill('here'); });
const promiseB1 = promiseB.then((value) => { console.log(`${value} a`); });
const promiseB2 = promiseB1.then((value) => { console.log(`${value} b`); });

如果想要在使用方法 B 中的第二次调用 then 时,value 有值,那么就需要在第一次调用 then 时返回数据,即

const promiseB = new Promise((fulfill, reject) => { fulfill('here'); })
                       .then((value) => { console.log(`${value} a`); return 'there'; })
                       .then((value) => { console.log(`${value} b`); });

此时,的输出结果为

here a
there b

References