Promise Microtask Queue执行顺序疑问:为何输出与预期不符?
两段Promise代码输出差异的原因解析
代码示例与输出差异
第一段代码执行后输出为 10, 1:
const p1 = new Promise((_, reject) => { reject(1); }).then((r)=>console.log(r)).catch((r)=>console.log(r)); const p2 = new Promise((resolve, _) => { resolve(10); }).then((r)=>console.log(r)).catch((r)=>console.log(r));
第二段代码执行后输出为 1, 10:
const p1 = new Promise((_, reject) => { reject(1); }).catch((r)=>console.log(r)) const p2 = new Promise((resolve, _) => { resolve(10); }).then((r)=>console.log(r)).catch((r)=>console.log(r));
疑问
按逻辑,p1的catch回调应早于p2的then回调被加入微任务队列,输出应为1, 10才对,为何第一段代码输出相反?
原因解释
核心在于Promise链式调用中,每个.then或.catch都会返回一个新的Promise,微任务的添加时机是当前链式调用中前一个Promise的状态确定之后。
第一段代码的执行流程
- p1的执行链:
- 初始Promise立即
reject(1),状态变为rejected。 - 调用
.then((r)=>console.log(r)):由于原Promise是rejected状态,这个then的回调会被直接跳过,同时该then返回一个新的Promise,状态也变为rejected,值为1。 - 只有当这个
then返回的新Promise状态确定为rejected后,后续的.catch回调才会被加入微任务队列。
- 初始Promise立即
- p2的执行链:
- 初始Promise立即
resolve(10),状态变为fulfilled。 - 调用
.then((r)=>console.log(r)):由于原Promise已经是fulfilled状态,这个then的回调会直接被加入微任务队列。
- 初始Promise立即
所以在第一段代码中,p2的then回调比p1的catch回调更早进入微任务队列,因此先输出10,再输出1。
第二段代码的执行流程
- p1的执行链:
初始Promise立即reject(1),状态变为rejected,后续的.catch回调直接被加入微任务队列(没有中间的.then环节)。 - p2的执行链:和第一段一致,
then回调被加入微任务队列,但晚于p1的catch回调。
因此第二段代码中p1的catch先执行,输出1,再输出10。
内容的提问来源于stack exchange,提问作者bored_coffee
相关产品推荐
相关产品推荐

