【发布时间】:2019-05-23 02:44:45
【问题描述】:
我们在我们的节点应用程序中为"unhandledRejection" 添加了一个事件处理程序,这个处理程序终止了进程(正如节点所说的将是默认的很快)。
但是,我们看到的事件似乎是多余的(或至少为时过早的)。
我们正在使用Q.allSettled(它处理被拒绝的承诺),我在调试器中看到承诺数组有两个元素,第一个 rejected 和第二个 pending(它将被解决)。在unhandledRejection 处理程序和allSettled 之后的then 中放置断点后,我首先得到unhandledRejection,然后立即得到then(因此拒绝 处理)。
unhandledRejection 的文档说(强调我的):
'unhandledRejection'事件在Promise被拒绝并且没有错误处理程序附加到 Promise 时发出在事件循环的一个轮次中。
我的假设是创建 promise 数组的机制在第一个 promise 被拒绝和数组创建之间阻塞,但我无法在玩具示例中重现这一点。
我能想出的最好的最小示例有点做作,但我认为它与我们的代码具有相同的根本原因。我在这里错过了什么吗?如果可以的话,node如何让unhandledRejection默认终止进程?
process.on("unhandledRejection", (reason, p) => {
console.error(`### Got unhandled rejection: '${reason}'`);
});
function doesNotFireUnhandledRejection() {
let rejected = Promise.reject('an error');
return new Promise((resolve, reject) => {
resolve(rejected);
})
.catch(err => console.log("Caught:", err));
}
function firesUnhandledRejection() {
let rejected = Promise.reject('an error');
return new Promise((resolve, reject) => {
setTimeout(() => resolve(rejected), 0);
})
.catch(err => console.log("Caught:", err));
}
顺便说一句,setImmediate 会发生相同的行为,但 process.nextTick 不会发生相同的行为(尽管我可以发誓上周 process.nextTick 确实导致事件触发...)。
【问题讨论】:
-
我知道您正在尝试创建一个最小示例来重现它,但是静态拒绝承诺的原因是什么,取回
promise对象,然后将其包装在resolve中另一个承诺? -
@quirimmo,没有。我试图创建一个更有意义的示例,但还没有成功(还没有?)
-
-
啊,好吧,我想我现在知道你的问题了。你的意思是,如果你引入超时,为什么第一次拒绝没有被捕获?
-
@blex 在现实生活中,创建原始拒绝的函数在下游,对于大多数返回常规拒绝的调用者来说很好。没有合理的理由将其(及其所有客户)更改为使用包装承诺。
标签: javascript node.js promise