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

时间:2016-11-09 20:09:51

标签: 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.

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

4 个答案:

答案 0 :(得分:7)

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

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

修改

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

<强> 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++);
  });
}

<强> 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);
  });

答案 1 :(得分:4)

通常,使用像bluebird这样的自定义库,您可以仅通过代码来抑制拒绝,而不是其他任何地方。本土承诺还不能做到这一点。

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

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

通过这种方式,你明确地忽略了对promise的拒绝,因此它不再是一个未处理的拒绝,只是一个被压制的拒绝。

答案 2 :(得分:1)

这不是你需要解决的问题。

按照预期的方式使用promises。如果最终用户不想处理所有拒绝,那么他们必须添加unhandledRejection处理程序。否则他们将需要添加捕获量。

如果您的错误确实没有破裂,那么您不应该拒绝它们。只需使用错误值解决。 e.g:

成功:resolve({result, error:null})

失败:resolve({result:null, error})

最好拒绝并让最终用户决定如何处理它。

答案 3 :(得分:0)

我无法弄清楚你所描述的任何方式。

如果您不关心向用户传递错误,可以在承诺链的末尾添加虚拟catch块:

Promise.reject('foo')
.catch(() => {})

这会使警告静音,但不允许用户处理错误。

也许您可以添加一个用户可以决定是否要处理错误的选项。