Node.js Process unhandledPromiseRejection 事件

2025年2月24日 | 阅读 4 分钟

Node.js 凭借其强大的运行时环境,允许开发人员在服务器端执行 JavaScript。它以事件驱动而闻名,并且基于 Chrome 中的 V8 JavaScript 引擎构建。非阻塞 I/O 模型使 Node.js 高效且轻量级。它非常适合开发可扩展的网络应用程序。处理 Node.js 需要深入了解它如何管理 Promise。在处理异步进程时尤其如此。

什么是 Node.js Promise?

Promise 现在可以管理异步 JavaScript 操作。与传统的 callback 方法相比,它们提供了更结构化、更可控的方式来处理异步代码。Promise 代表一个预期在未来完成的任务。它可能处于挂起、已完成或已拒绝三种状态之一。Promise 变为已完成,表示该过程成功。它在控制台产生了预期的结果。当操作失败时,Promise 被拒绝就表示这一点。它通常包含一个 error 对象作为失败的原因。

未处理的 Promise 拒绝问题

随着 ES2017 中 async/await 语法的出现,Promise 在 Node.js 上下文中越来越普及。然而,当一个 Promise 被拒绝,并且没有处理器来处理该拒绝时,这是一个常见的问题。这被称为未处理的 Promise 拒绝。

当发生未处理的 Promise 拒绝时,意味着一个 Promise 已失败,并且没有提供 .catch() 方法或拒绝处理器来处理错误。错误的来源可能不那么明显,导致意外行为并使故障排除复杂化。

Node.js Process unhandledRejection 事件

Node.js 提供了一个全局的未处理拒绝事件来解决未处理的 Promise 拒绝问题。每次 Promise 被拒绝,并且在事件循环的当前周期中没有连接拒绝处理器时,就会发出此事件。

下面是一个演示未处理拒绝事件用法的简单示例。

此示例定义了一个回调函数来处理 unhandledRejection 事件。该事件是为被拒绝的 Promise 监听的,而拒绝的原因是传递给回调函数的两个输入。一个输入通常是一个 error 对象。

处理未处理的拒绝

Node.js 应用程序可以通过使用 unhandledRejection 事件来全局处理未处理的 Promise 拒绝。这有助于资源清理、错误报告,甚至平缓的程序关闭。

1. 使用 async/await 和 try/catch:在使用 async/await 语法时,将异步代码包含在 try/catch 块中以处理失败。

输出

Node.js Process unhandledPromiseRejection Event

2. 集中式错误处理:对于大型系统,我们应该考虑实现集中式错误处理逻辑。为此,我们应该构建实用函数,以统一处理我们应用程序中的错误。

输出

Node.js Process unhandledPromiseRejection Event

弃用和未来更改

Node.js 处理未处理 Promise 拒绝的方式已随时间而改变。重要的是要注意,在 Node.js 的早期版本中,未处理的 Promise 拒绝被默认忽略。从 Node.js 10 开始,记录警告是默认做法。

后续版本已包含其他更改。这些提供了改进的工具来管理未处理的 Promise 拒绝。使用 Node.js 15 及更高版本,--unhandled-rejections 命令行选项允许我们修改未处理 Promise 拒绝的默认操作。此标志可以具有以下值之一。

  • 严格(未来版本的默认值):抛出错误并终止进程。
  • 警告:发出警告。继续操作(Node.js 15 中的默认值)。
  • 无:不执行任何操作。

结论

总之,管理未处理的 Promise 拒绝是开发可靠 Node.js 应用程序的最重要方面之一。开发人员可以通过利用 unhandledRejection 事件全局检测和处理故障来提高应用程序的稳定性。最佳实践是直接在代码中处理 Promise 拒绝,并提供一致且可预测的错误处理。跟踪错误处理技术的变化可以帮助开发人员。随着 Node.js 的不断发展,这将有助于构建更强大、性能更高的应用程序。