Promise 未捕获 reject 错误处理指南

当 Promise 被 reject 且未处理时,浏览器会显示 "Uncaught (in promise)" 错误。


本文介绍了三种常见未处理情况:

  • 直接 reject
  • async 函数抛出错误
  • then 链中未捕获的错误

提供了四种处理方法:

  • 使用 .catch()
  • try...catch
  • Promise 构造函数内部捕获
  • 全局事件监听(unhandledrejection)

最佳实践建议始终为 Promise 添加错误处理,包括使用空 catch 处理不关心的结果,以及使用 Promise.allSettled 处理并行操作。


这些方法能有效防止应用因未处理的 Promise 错误而崩溃,同时改善调试体验。


关联阅读推荐


JavaScript Promise 总结(附:常见返回 Promise 的API,ServiceWorker 中 Promise)


Promise 未捕获 reject 错误处理指南


当 Promise 被 reject 且没有相应的错误处理时,浏览器控制台确实会显示警告/错误。


具体表现

在 Chrome DevTools 中,你会看到类似这样的错误:

复制代码
Uncaught (in promise) Error: Something went wrong
    at <anonymous>:1:20

为什么会出现这个警告?


Promise 的设计哲学是:每个 reject 都应该被处理。


如果 reject 没有被捕获,JavaScript 引擎认为这可能是一个未被注意的错误。


示例代码

javascript 复制代码
// 情况1:直接 reject 没有被处理
const promise1 = new Promise((resolve, reject) => {
  reject(new Error('Something went wrong'));
});
// 控制台会显示:Uncaught (in promise) Error: Something went wrong

// 情况2:async 函数中 throw 没有被捕获
async function failedAsync() {
  throw new Error('Async error');
}
failedAsync(); // 同样会显示未捕获的 promise 错误

// 情况3:then 链中的 reject 没有被后续的 catch 处理
Promise.resolve()
  .then(() => {
    throw new Error('Error in then');
  });
// 这里虽然看起来有 then,但没有 catch,所以错误仍未被捕获

如何正确处理?

1. 使用 .catch()

javascript 复制代码
promise
  .then(result => {
    // 处理成功情况
  })
  .catch(error => {
    // 处理 reject 和 then 中抛出的错误
    console.error('Caught error:', error);
  });

2. 使用 try...catch 处理 async/await

javascript 复制代码
async function handleAsync() {
  try {
    await someAsyncFunction();
  } catch (error) {
    console.error('Caught error:', error);
  }
}

3. 在 Promise 构造函数中捕获错误

javascript 复制代码
const safePromise = new Promise((resolve, reject) => {
  try {
    // 可能出错的代码
    const result = riskyOperation();
    resolve(result);
  } catch (error) {
    reject(error);
  }
});

4. 全局捕获未处理的 Promise 错误

javascript 复制代码
// 在浏览器中
window.addEventListener('unhandledrejection', event => {
  console.warn('未处理的 Promise 拒绝:', event.reason);
  event.preventDefault(); // 阻止默认的控制台错误
});

// 在 Node.js 中
process.on('unhandledRejection', (reason, promise) => {
  console.log('未处理的拒绝:', reason);
});

最佳实践建议

  1. 总是为 Promise 链添加错误处理

  2. 在 async 函数中总是使用 try...catch

  3. 对于不关心结果的 Promise,至少加上一个空的 catch

    javascript 复制代码
    someAsyncOperation().catch(() => {});
  4. 对于可能失败的多个并行操作,使用 Promise.allSettled

    javascript 复制代码
    const results = await Promise.allSettled(promises);
    results.forEach(result => {
      if (result.status === 'rejected') {
        console.log('失败:', result.reason);
      }
    });

这样可以确保你的应用不会因为未处理的 Promise 错误而崩溃,同时也能获得更好的调试体验。

相关推荐
叫我一声阿雷吧1 天前
JS 入门通关手册(42):Promise 并发控制(all/race/allSettled/any 手写 + 实战)
javascript·promise·并发控制·promise.all·js异步编程·promise.race·手写promise
itman3013 天前
C语言errno.h头文件:错误处理机制及errno变量特点说明
c语言·错误码·库函数·错误处理·errno.h
牛奶3 天前
setTimeout设为0就马上执行?JS异步背后的秘密
前端·性能优化·promise
木斯佳13 天前
前端八股文面经大全:bilibili前端一面(2026-03-26)·面经深度解析
前端·面试·笔试·校招·promise
乘方16 天前
Promise/A+ 解析
promise
叫我一声阿雷吧19 天前
JS 入门通关手册(24):Promise:从回调地狱到异步优雅写法
javascript·前端开发·promise·前端面试·异步编程·js进阶·js异步
前端小D24 天前
ES6 中的 Promise
前端·javascript·es6·promise
小怪点点1 个月前
手写promise
前端·promise
willow1 个月前
Promise由浅入深
javascript·promise