promise.then回调按注册顺序进入微任务队列,总在同步代码后、宏任务前执行;链式调用中返回值决定下个then输入,错误由catch或rejection handler捕获,均走微任务流程。
promise.then 的回调执行顺序由 javascript 的事件循环机制决定,不是靠手动“把控”,而是遵循明确的规则:所有 then 回调都进入微任务队列(microtask queue),按注册顺序、在当前同步代码执行完后、下一个宏任务开始前统一执行。
then 回调一定异步执行
即使 Promise 已经处于 fulfilled 状态,.then 的回调也不会立即运行,而是被放入微任务队列。这意味着它总在当前同步代码之后、setTimeout 等宏任务之前执行。
- 例如:
Promise.resolve().then(() => console.log('a')); console.log('b');输出一定是b然后a - 哪怕链式调用多个 then,它们也按注册顺序依次入队,不会因为 Promise 状态已定就“插队”
链式调用中,每个 then 的返回值决定下一个 then 的输入
前一个 then 的回调返回值(无论普通值还是新 Promise)会作为参数传给下一个 then 的回调。这个传递过程本身不改变执行时机,但会影响后续微任务的触发节奏。
- 返回普通值 → 下一个 then 立即拿到该值,其回调进入微任务队列
- 返回 Promise → 下一个 then 要等该 Promise settle 后,再把结果传入,回调仍进微任务队列,但时间点延后
- 错误会被 catch 或后续带 rejection 处理的 then 捕获,同样走微任务流程
想控制“先后”,关键在 Promise 的创建和 resolve 时机
真正影响执行顺序的,不是 .then 本身,而是 Promise 何时被 resolve/reject,以及你是否在 then 中返回新的异步操作。
- 多个独立 Promise 的 then,谁先 resolve,谁的 then 就先排队;resolve 时间相同,则按代码书写顺序排队
- 如果需要严格串行,用链式写法:
p1.then(...).then(...).then(...) - 如果需要并行后统一处理,用
Promise.all([p1, p2]).then(...),所有 Promise 都 settle 后才触发 then
避免常见误解:不要试图用 setTimeout 控制 then 顺序
给 then 加 setTimeout 反而把它从微任务降级为宏任务,打乱原本的执行优先级,容易引发竞态或逻辑错乱。
- 错误做法:
promise.then(() => setTimeout(() => {...}, 0))—— 这会让逻辑延迟到下一轮事件循环,失去 Promise 的时序保障 - 正确思路:把异步逻辑封装进 Promise,让 then 自然承接,保持微任务一致性











