我在Node.js中做了很多带有回调的异步编码和优秀的异步库,效果很好。我正在尝试使用一个使用promises的模块,但是我遇到了一个问题,即在promise之后抛出的任何错误仍然被冒充并被promise错误处理程序捕获。
这使得调试错误非常困难,因为我不知道它们会弹出的位置,也不会抛出它们,也不会使应用程序崩溃。
以下示例代码;我想要做的就是退出promise链并在解决后将其留下,而不是捕获与之无关的所有后续错误。
function one (input, callback) {
doSomeAsyncWork(input)
.then(function (result) {
return callback(null, result);
})
.catch(function (err) {
logError(err);
return callback(err);
});
}
function two (err, result) {
if (err) { ... }
var x = callAMethodThatThrows();
...
}
one('abc', two);
在此示例中,方法 callAMethodThatThrows()会抛出一个错误,该错误会冒泡到promise catch()块。这可以防止应用程序崩溃并使其处于未知状态。
非常感谢任何建议,谢谢。
答案 0 :(得分:3)
是的,抱歉 - 我们正在修复(1)Node中的默认行为。与此同时,我推测并Petka添加了(在其他人的支持下)用于查找这些错误的钩子:
process.on("unhandledRejection", (err, p) => {
console.error(err); // print the error
});
请注意,如果您本身异步执行.catch
,这可能会产生一些误报 - 根据我的经验非常罕见。
另请注意,对于承诺,您的服务器通常不处于未知状态,并且可以并且应该在有意义时尝试从错误中恢复。由于promises一直意味着抛出安全的代码,因此可以进行细粒度的错误处理。
请注意,promises使异步库很大程度上不需要。如果你仍然希望使用回调,只是希望"那些讨厌的承诺"会让你独自一人,让你继续写回调,这很好 - 承诺是安全的,但你可以通过执行 off 承诺代码来逃避:
myPromiseFn().then(v => {
process.nextTick(() => cb(null, v)); // next tick, to escape the chain
}, e => process.nextTick(() => cb(e));
请注意,公平承诺库还带有asCallback
回调,用于将promise代码转换为节点err-back回调。
(1)有些人声称没有问题,请参见图
答案 1 :(得分:1)
感谢Ben的回答,我发现可以使用诸如nodeify之类的模块将承诺转换为回调。这允许我们使用回调来保留所有代码,并避免错误被承诺吞噬。非常有用。