Promise 构造函数内部用 try-catch 同步包裹执行器函数,捕获到异常即自动调用 reject,使状态立即变为 rejected;异步抛出的异常则无法被捕获,需手动调用 reject。

Promise 构造函数中,如果在执行器(executor)函数内部**同步抛出异常**(比如 throw new Error()),Promise 会立即进入 rejected 状态,且该异常会被自动捕获并作为 rejection reason。
为什么能自动转为 rejected?
Promise 规范(如 Promises/A+ 和 ECMAScript 标准)明确规定:执行器函数是**同步执行的**,且 Promise 实现必须对 executor 内部的同步异常进行捕获。一旦捕获到,就等价于调用了 reject(reason)。
这并非“隐式转换”,而是 Promise 构造函数内部做了 try-catch 包裹:
- 构造函数调用 executor 时,会用 try-catch 捕获其同步执行过程中的任何错误
- 若 catch 到错误,就以该错误为 reason,调用内部的 reject 流程
- 因此 Promise 实例的状态从
pending直接变为rejected,不会停留在 pending
代码验证示例
以下代码会立即进入 rejected 状态:
立即学习“Java免费学习笔记(深入)”;
const p = new Promise((resolve, reject) => {throw new TypeError('Oops'); // 同步 throw
});
p.catch(err => console.log(err.message)); // 输出: "Oops"
注意:此时 p 的状态已是 rejected,即使没有 .catch,也会触发未处理 rejection 警告(在 Node.js 或现代浏览器控制台中可见)。
和异步抛出的区别
若异常发生在异步任务中(如 setTimeout、fetch 回调内),则不会被 Promise 构造函数捕获,状态也不会自动变 rejected:
const p2 = new Promise((resolve) => {setTimeout(() => {
throw new Error('Async error'); // 不会影响 p2 状态
}, 0);
});
// p2 保持 pending,且该 throw 会变成未捕获异常
这种情况下,必须显式调用 reject() 才能改变状态。
实际使用建议
- 同步错误(如参数校验失败、JSON.parse 失败)可直接 throw,Promise 会帮你处理
- 避免在 executor 中混用同步 throw 和手动 resolve/reject —— 逻辑易混乱,且 throw 后的代码不执行,但 resolve/reject 不会自动取消
- 想确保错误被处理,始终为 Promise 链添加
.catch()或await并用 try/catch 包裹


















