在Node.js 7中,什么是压缩UnhandledPromiseRejectionWarning的正确方法?

Vol*_*lov 9 javascript node.js promise

在Node.js中,我有一个只包含一个函数的模块.该函数返回promise并且可以拒绝promise.我仍然不想强制模块的所有用户明确地处理拒绝.在某些情况下,通过设计,忽略返回的promise是有意义的.此外,我不希望能够处理远离模块用户的承诺拒绝.

正确的方法是什么?

升级到Node.js 7.1.0后,忽略拒绝处理的所有单元测试都显示以下警告:

(node:12732) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: try to throw an error from unit test
(node:12732) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Run Code Online (Sandbox Code Playgroud)

DeprecationWarning描述中提到的将来阻止终止Node.js进程的正确方法是什么?

pet*_*teb 7

如果您担心未处理的拒绝导致Nodejs进程在将来无意中终止,您可以在对象上注册'unhandledRejection'事件的事件处理程序process.

process.on('unhandledRejection', (err, p) => {
  console.log('An unhandledRejection occurred');
  console.log(`Rejected Promise: ${p}`);
  console.log(`Rejection: ${err}`);
});
Run Code Online (Sandbox Code Playgroud)

编辑

如果您希望模块的实现用户决定是否在其代码中处理错误,您应该将您的承诺返回给调用者.

yourModule.js

function increment(value) {
  return new Promise((resolve, reject) => {
    if (!value)
      return reject(new Error('a value to increment is required'));                  

    return resolve(value++);
  });
}
Run Code Online (Sandbox Code Playgroud)

theirModule.js

const increment = require('./yourModule.js');

increment()
  .then((incremented) => {
    console.log(`Value incremented to ${incremented}`);
  })
  .catch((err) => {
    // Handle rejections returned from increment()
    console.log(err);
  });
Run Code Online (Sandbox Code Playgroud)


Ben*_*aum 7

一般来说,使用像 bluebird 这样的自定义库,您可以仅从代码中抑制拒绝,而不能在其他任何地方抑制拒绝。本机承诺还不能做到这一点。

但是,您可以通过为其添加捕获处理程序来手动抑制承诺。

 function yourExportedFunction() {
     const p = promiseThatMightRejectFn(); 
     p.catch(() => {}); // add an empty catch handler
     return p;
 }
Run Code Online (Sandbox Code Playgroud)

这样你就明确地忽略了承诺的拒绝,所以它不再是一个未经处理的拒绝,只是一个被压制的拒绝。

  • @VolodymyrFrolov 用户只需在他们身边添加一个 `.catch(error => handleError(error))` 就好了 - 这个答案不限制 - 自己尝试 - 我们不会改变原始承诺。 (2认同)
  • Benjamin 是对的 Volodymyr,他返回的是 `p` 而不是 `p.catch(() => {})`。他基本上分叉了承诺,但是因为一个分叉有一个捕获,另一个分叉不会触发`UnhandledPromiseRejectionWarning` (2认同)
  • @NicholasCarey 不,它分叉承诺并解决_那个_承诺,它对原始承诺没有任何作用。 (2认同)