Promise.catch是微任务,非同步执行,等当前同步代码和微任务队列清空后才运行;它捕获的是前一个Promise的rejection状态,错误值透传,未捕获则触发unhandledrejection事件。

Promise.catch 不是“立刻执行”的错误处理器,而是把错误处理逻辑放进微任务队列,等当前同步代码跑完、本轮事件循环的微任务清空时才真正运行。
catch 本质是微任务,不是同步调用
哪怕 Promise 立即被 reject(比如 Promise.reject(new Error('boom'))),它的 .catch() 回调也不会马上执行。它会被推入微任务队列(PromiseJobs),排在当前脚本执行完毕之后、下一个宏任务(如 setTimeout)之前运行。
- 同步代码优先执行,包括 Promise 构造器内的所有同步逻辑
- 所有
.then/.catch/.finally的回调都进微任务队列,按注册顺序排队 - 微任务队列是 FIFO(先进先出),但会等当前调用栈清空后统一执行
链式调用中 catch 捕的是谁的错?
关键点在于:.then() 总是返回一个新 Promise,而 .catch() 监听的是它前面那个 Promise 的 rejection —— 不是原始 Promise,也不是中间抛出的新错误,而是该链节点的直接状态。
- 如果
.then(onFulfilled)没传第二个参数,且上游被 reject,这个.then就跳过,新 Promise 立即进入 rejected 状态 - 后续的
.catch()捕获的就是这个“衍生 Promise”的 rejection,不是原始错误本身,但错误值会透传 - 多个 Promise 并行触发时,它们各自的
.catch()会按微任务入队顺序执行,不保证与 reject 调用顺序一致
未捕获的 rejection 会怎样?
没有 .catch() 或 .then(null, handler) 的 Promise rejection,不会中断程序,但会在微任务队列清空后触发 unhandledrejection 全局事件。
- 浏览器中表现为控制台警告
Uncaught (in promise) … - Node.js 中触发
process.on('unhandledRejection', ...),默认不退出进程,但未来版本可能改变行为 - 这说明错误没消失,只是没人处理;线上应监听该事件并记录日志
怎么写更可靠的错误处理?
别依赖“最后加一个 .catch”来兜底。真实场景里,每个异步环节都可能失败,需要分层响应。
- 单个请求失败:用
.catch()做 UI 提示或降级(如显示缓存数据) - 并行请求(
Promise.all):任一失败就整体 reject,适合强一致性场景;改用Promise.allSettled可分别处理每个结果 - 链式流程中关键步骤:在
.then()内部 throw 错误,让它自然冒泡到最近的.catch() - 避免在
.then()第二个参数里处理错误——语义不清,且无法捕获内部throw


















