【问题标题】:Promises not catching error correctly NodeJS承诺不能正确捕捉错误 NodeJS
【发布时间】:2016-11-10 06:30:32
【问题描述】:

如果我没记错的话,Promise 应该在任何时候都抛出错误时捕获错误,以便 Promise.catch() 可以用来处理该错误。我不记得有任何异常,但是当我在 setTimeout() 中抛出错误时,这不知何故不起作用。

有人可以解释为什么这不起作用吗?还是仅仅是 NodeJS 中的一个错误?

测试代码

// This works!
function async() {
        return new Promise(function (resolve, reject) {
                throw new Error('test');
        });
}

async().catch(function() {
        console.log('Ok: 1');
});


// This doesn't work..
function async_fail() {
        return new Promise(function (resolve, reject) {
                setTimeout(function() {
                        throw new Error('test');
                }, 1);
        });
}

async_fail().catch(function() {
        console.log('Ok: 2');
});

【问题讨论】:

  • 为什么在 promise 中需要setTimeout...如果您使用的是BlueBird.delay 不应该更好吗? bluebirdjs.com/docs/api/promise.delay.html
  • @DavidEspino 你是对的,但是如果我使用的 npm 包之一使用setTimeout 怎么办?然后我的代码会崩溃,因为Promise.catch 没有触发:/ 我也想知道为什么会发生这种情况。
  • 所以...您无法控制setTimeout 将执行什么?如果你有我认为这只是问题或resolvingrejecting 该函数中的承诺......对吗?看看这个stackoverflow.com/questions/22707475/…...也许这会有所帮助...大多数npm包都是基于callback...所以我想如果你有一个内部执行setTimeout的包.. . 95% 确定您可能有callback 选项...如果没有...恕我直言,那是 baaaad npm 包:)...
  • 这实际上是你可以使用的一个技巧:看这个this answer

标签: javascript node.js error-handling es6-promise


【解决方案1】:

你永远不会捕获在 setTimeout 中抛出的错误,因为它与 promise 函数的实际执行异步执行。因此,当调用 set timeout 内的函数时,promise 本身已经完成(没有任何调用来解决或拒绝)。

如果您希望承诺因 setTimeout 内的错误而失败,您需要手动捕获它并调用拒绝:

setTimeout(function() {
     try{
          throw new Error('test');
     }catch(ex){
          reject(ex);
     }
}, 1);

【讨论】:

  • 或者,他可以使用setTimeout 的承诺版本,对吗?
  • @Tom 当然可以,但我不知道这样一个承诺的setTimeout 的香草 js 版本,所以它可能取决于您使用的库/包装器。一般来说,我希望这些包装器中的任何一个都能在 setTimeout 中捕获错误并拒绝您的承诺。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-15
  • 1970-01-01
  • 1970-01-01
  • 2020-06-23
  • 2017-09-27
  • 2016-10-05
  • 2020-03-16
相关资源
最近更新 更多