javascript – NodeJS UnhandledPromiseRejectionWarning

所以,我正在测试一个依赖于事件发射器的组件.为此,我想出了一个使用Promise with Mocha Chai的解决方案:

it('should transition with the correct event', (done) => {
  const cFSM = new CharacterFSM({}, emitter, transitions);
  let timeout = null;
  let resolved = false;
  new Promise((resolve, reject) => {
    emitter.once('action', resolve);
    emitter.emit('done', {});
    timeout = setTimeout(() => {
    if (!resolved) {
      reject('Timedout!');
    }
    clearTimeout(timeout);
  }, 100);
}).then(((state) => {
      resolved = true;
      assert(state.action === 'DONE', 'should change state');
      done();
    }))
    .catch((error) => {
      assert.isNotOk(error,'Promise error');
      done();
    });
  });
});

在控制台上我得到一个’UnhandledPromiseRejectionWarning’,即使拒绝函数被调用,因为它立即显示消息’AssertionError:Promise error’

(node:25754) UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 2): AssertionError: Promise error: expected
{ Object (message, showDiff, …) } to be falsy
1) should transition with the correct event

然后,在2秒后我得到了

Error: timeout of 2000ms exceeded. Ensure the done() callback is
being called in this test.

自从执行catch回调以来,这甚至更奇怪.(我认为由于某种原因,断言失败阻止了其余的执行)

现在有趣的是,如果我注释掉assert.isNotOk(错误…),测试运行正常,没有控制台中的任何警告.它执行捕获的意义上仍然“失败”.
但是,我仍然无法理解这些错误.有人可以开导我吗?

解决方法:

问题是由此造成的:

.catch((error) => {
  assert.isNotOk(error,'Promise error');
  done();
});

如果断言失败,则会抛出错误.此错误将导致done()永远不会被调用,因为代码在它之前出错了.这就是造成超时的原因.

“Unhandled promise rejection”也是由失败的断言引起的,因为如果在catch()处理程序中抛出错误,并且没有后续的catch()处理程序,则会吞下错误(如this article中所述) . UnhandledPromiseRejectionWarning警告提醒您注意这一事实.

一般来说,如果你想在Mocha中测试基于promise的代码,你应该依赖Mocha本身可以处理promise的事实.您不应该使用done(),而是从测试中返回一个promise.然后摩卡会捕捉到任何错误.

像这样:

it('should transition with the correct event', () => {
  ...
  return new Promise((resolve, reject) => {
    ...
  }).then((state) => {
    assert(state.action === 'DONE', 'should change state');
  })
  .catch((error) => {
    assert.isNotOk(error,'Promise error');
  });
});

相关文章

最后的控制台返回空数组.控制台在ids.map函数完成之前运行va...
我正在尝试将rxJava与我已经知道的内容联系起来,特别是来自J...
config.jsconstconfig={base_url_api:"https://douban....
我正在阅读MDN中的javascript,并且遇到了这个谈论承诺并且不...
config.jsconstconfig={base_url_api:"https://douban....
这是我的代码main.cpp:#include<string>#include<...