为何下述JavaScript代码中resolve先输出而非reject?
问题解析:为何resolve结果先输出?
首先看代码:
[Promise.reject(42), Promise.resolve(4)].forEach((item, i) => { Promise.resolve(item) .then(() => console.log("resolve", i)) .catch(() => console.log("reject", i)); });
预期输出:
reject 0 resolve 1
实际输出:
resolve 1 reject 0
核心原因:Promise链的异步调度顺序差异
我们把代码拆解成两个独立的Promise链来分析:
1. 处理第一个元素(Promise.reject(42),i=0)
Promise.resolve(item)直接返回这个已拒绝的Promise(输入为Promise对象时,Promise.resolve会复用它的状态)。- 调用
.then(() => console.log("resolve", 0)):原Promise是拒绝状态,这个then的回调不会执行,但会返回一个pending状态的新Promise。 - 这个新Promise会被安排一个微任务,任务内容是把它的状态改为拒绝(继承原Promise的拒绝原因)。
- 调用
.catch(() => console.log("reject", 0)):该catch注册在上述新Promise上,只有等新Promise变为拒绝状态后,它的回调才会被加入微任务队列。
2. 处理第二个元素(Promise.resolve(4),i=1)
Promise.resolve(item)直接返回这个已决议的Promise。- 调用
.then(() => console.log("resolve", 1)):原Promise是已决议状态,这个then的回调会被直接加入微任务队列,等待执行。
微任务队列的执行顺序
同步代码执行完毕后,微任务队列的初始任务顺序是:
- 执行第二个Promise链的
then回调(输出resolve 1) - 处理第一个Promise链中
then返回的Promise的状态变更,将其改为拒绝,再把catch回调加入微任务队列
等第一个任务执行完成,才会执行新加入的catch回调,输出reject 0。
内容的提问来源于stack exchange,提问作者Shivam
相关产品推荐
相关产品推荐

