new Promise 的 executor 同步抛异常不会被 Promise 捕获,而是立即作为同步错误抛出,必须用 try...catch 包裹 new Promise 才能捕获;若在 executor 内做可能失败的同步操作,应在其内部用 try...catch 调用 reject 转为 Promise rejection。

当 new Promise 时传入的 executor 函数(即构造函数的第一个参数)直接抛出异常,这个异常**不会被 Promise 内部捕获**,而是作为**同步异常**立即抛出,必须用 try...catch 捕获,无法通过 .catch() 或 await 捕获。
executor 抛异常是同步行为
Promise 构造函数会立即同步执行 executor 函数。如果 executor 内部有 throw new Error(...) 或运行时报错(如访问 undefined.method()),JS 引擎会立刻中断 executor 执行,并把错误抛到外层调用栈,就像普通函数抛错一样。
- 它根本没机会进入 Promise 的异步状态机(pending → fulfilled/rejected)
- 此时 Promise 实例甚至还没“真正开始”,其状态仍是
pending,但已无法被.then/.catch触发 -
await对它完全无效,因为没有 Promise 被 resolve/reject,await等不到任何东西就会直接报错
正确捕获方式:用 try...catch 包裹 new Promise
要捕获 executor 同步抛出的错误,必须在外层用 try...catch:
try {
const p = new Promise((resolve, reject) => {
throw new Error('executor 同步炸了');
});
} catch (e) {
console.log(e.message); // ✅ 能捕获
}
注意:不能写成 new Promise(...).catch(...),这毫无作用——Promise 都没创建成功,.catch 方法根本没机会被调用。
立即学习“Java免费学习笔记(深入)”;
常见易错场景
-
误以为 await 可以兜底:
const res = await new Promise(...)中,若 executor 同步抛错,await还没开始就已报错,不会进入 async 函数的 rejection 流程 -
在 Promise.all 中忽略 executor 错误:如果某个子 Promise 的 executor 同步抛错,
Promise.all会立即 reject,但错误来自构造阶段,不是子 Promise 的 rejection 值 -
混淆“executor 抛错”和“executor 中异步操作出错”:比如
setTimeout(() => { throw ... })是异步抛错,不会影响 Promise 构造,此时 Promise 保持 pending,错误会变成未捕获异常(unhandled rejection)
最佳实践建议
- 尽量避免在 executor 中做可能同步失败的操作(如解析 JSON、校验参数),提前在
new Promise外校验 - 如果必须在 executor 中处理可能出错的同步逻辑,用
try...catch在内部调用reject,把同步错误转为 Promise rejection:
const p = new Promise((resolve, reject) => {
try {
const data = riskySyncOperation(); // 可能 throw
resolve(data);
} catch (e) {
reject(e); // ✅ 转为 Promise rejected 状态
}
});
这样就能用 .catch() 或 await 正常处理了。


















