考虑一下:
const a = () => {
return new Promise((resolve) => {
resolve(1);
});
};
const b = () => {
return new Promise((resolve) => {
a()
.then((aR) => {
console.log(aR);
resolve(2);
})
.finally(() => {
console.log("A");
});
});
};
const c = () => {
b().then((bR) => {
console.log(bR);
});
};
c();
为什么会打印
1 2 A
、not 1 A 2
?
这个问题最初是由@rebuilding127在类似StackOverflow的中文论坛Segmentfault上发现的。我认为值得在这里翻译和发布。
你可以看到这个链式调用:
a()
.then((aR) => {
console.log(aR);
resolve(2);
})
.finally(() => {
console.log("A");
});
这是一个链式调用,其中
a().then(...)
返回一个Promise
,它将在返回的A
满足后输出Promise
,而不是在a()
满足后输出。因此,在满足 resolve(2)
并入队 b().then
之前,a().then
将入队 a().finally
。
为了更清楚,我重写了代码:
const f = () => {
const a = new Promise((resolve) => {
const cb1 = (result1) => {
console.log(result1);
resolve(2);
};
const cbA = () => console.log('A');
const b = Promise.resolve(1);
const c = b.then(cb1);
c.finally(cbA);
});
return a;
};
const cb2 = (result2) => console.log(result2);
f().then(cb2);
执行过程如下:
f
a
b
立即得到满足,导致 cb1
被排入微任务队列(现在队列 = [cb1]
)c
的执行者入队f
回归cb1
(现在队列=[]
)1
,解析 a
,导致 cb2
入队(现在队列 = [cb2]
)cb1
返回,导致 c
被解析,然后 cbA
被排队(现在队列 = [cb2, cbA]
)cb2
(现在队列=[cbA]
)2
cbA
;现在队列 = []
.A
,勾选结束还在 SegmentFault 上的原始问题下发布了。