promise的多个then回调按注册顺序入微任务队列,当前宏任务结束后依次同步执行。同一promise的多个独立then输出顺序与注册顺序一致,链式调用中a→b→c严格串行且同轮微任务完成。

Promise的多个then回调在同一个Event Loop循环中,并不是“排队等待执行”,而是**按注册顺序被推入微任务队列(microtask queue)**,并在当前同步任务结束后、下一个宏任务开始前,**依次、同步地执行**。
微任务队列的先进先出(FIFO)机制
当一个Promise状态变为fulfilled或rejected时,它关联的所有then(或catch)回调会被作为微任务加入微任务队列。浏览器/Node.js保证:
- 微任务队列是单个先进先出队列,不区分Promise来源;
- 所有已注册的
then回调,按它们被调用的先后顺序入队; - 当前宏任务(如script、setTimeout回调)执行完后,引擎会清空整个微任务队列——逐个取出并同步执行,中间不穿插其他代码。
链式调用中then的注册与执行顺序一致
写法如p.then(a).then(b).then(c),看似“链式”,实则是:
-
p.then(a)返回新Promise,同时把a注册为p的fulfill handler; -
.then(b)注册在上一个then返回的Promise上,所以b必须等a执行完毕、返回值被resolve后才可能触发; - 因此
a → b → c不仅入队顺序固定,执行也严格串行,且都在同一轮微任务清空过程中完成。
多个独立then对同一Promise,也是注册即入队
比如:
const p = Promise.resolve(1);p.then(() => console.log('1'));
p.then(() => console.log('2'));
p.then(() => console.log('3'));
输出一定是1 2 3。原因:
- 三个
then几乎同时调用(同步阶段),注册顺序即入队顺序; -
p已处于fulfilled状态,每个then立即生成微任务; - 微任务队列最终包含[handler1, handler2, handler3],依次执行。
注意:then回调内部的异步操作不影响微任务排队本身
then回调函数体内的代码是同步执行的。如果它内部又返回Promise或调用setTimeout,那属于新的任务调度,和当前这轮微任务排队无关:
-
then(() => Promise.resolve().then(() => console.log('nested'))):外层回调同步执行,返回的Promise会触发一个新的微任务(排在当前队列末尾,下一轮微任务才执行); -
then(() => setTimeout(() => console.log('macro'), 0)):setTimeout产生宏任务,一定晚于所有当前微任务。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











