promise内部同步抛出的异常(如executor中直接throw、json.parse错误、undefined.foo等)会被自动捕获并转为rejected状态;异步回调、resolve后throw、微任务中throw则不会被自动捕获,需手动try/catch+reject。

在 Promise 内部,同步抛出的异常(比如直接写 throw new Error() 或调用一个必然报错的同步函数)会被自动捕获,并导致该 Promise 立即变为 rejected 状态,无需额外 try/catch —— 但前提是异常发生在 Promise 构造函数的执行器(executor)函数中,且是**同步执行路径**上。
哪些情况算“Promise 内部同步抛出”?
以下代码中的 throw 都属于 Promise 内部同步抛出,会正确 reject:
new Promise((resolve, reject) => { throw new Error('boom'); })-
new Promise((resolve, reject) => { JSON.parse('{invalid}'); })(语法错误同步抛出) -
new Promise((resolve, reject) => { undefined.foo(); })(TypeError 同步抛出)
哪些情况不会被自动捕获?
以下看似在 Promise “里面”,但因异步或脱离 executor 执行上下文,异常会漏出变成未捕获错误(Uncaught Error):
-
new Promise((resolve, reject) => { setTimeout(() => { throw new Error(); }, 0); })→ 异步回调中抛出,不被捕获 -
new Promise((resolve, reject) => { resolve(); throw new Error(); })→resolve()已调用,Promise 已进入 fulfilled 状态,后续 throw 不影响状态,但会作为未处理异常抛出 -
new Promise((resolve, reject) => { Promise.resolve().then(() => { throw new Error(); }); })→ 微任务中抛出,不属于 executor 同步执行流
如何安全处理?推荐做法
对同步逻辑,靠 Promise 自动捕获即可;对可能异步抛出的部分,需主动用 try/catch 包裹,并显式调用 reject:
- 在 executor 中对所有可能同步失败的操作(如 JSON.parse、正则 exec、对象属性访问等)保持自然写法,不用包 try/catch —— Promise 已帮你兜底
- 如果逻辑含异步步骤(如 setTimeout、事件监听、fetch.then),且你希望把其中的异常转为 Promise rejection,则必须手动 try/catch 并调用
reject(err) - 避免在 resolve/reject 调用后继续执行可能抛错的代码,防止静默异常
验证方式:用 .catch() 或 top-level await 捕获
同步抛出的异常生成的 rejected Promise,可通过标准方式处理:
new Promise(...).catch(err => console.error(err.message))- 或用 async/await:
try { await new Promise(...); } catch (e) { ... } - 注意:未加
.catch()或未 await 的 rejected Promise,在现代环境会触发unhandledrejection事件
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











