我正在使用 Promise.all 并捕获错误,但仍然收到未处理的拒绝
const Promise = require('bluebird');
function sleep(milis) {
return new Promise(function(resolve, reject) {
if (milis == 1000) {
console.log('Rejecting millis', milis)
setTimeout(() => {
reject('Got error')
}, milis);
} else {
console.log('Processing millis', milis)
setTimeout(() => {
resolve(milis);
}, milis);
}
});
}
function test() {
try {
let lists = [2000, 1000, 3000]
Promise.all(
lists.map(record => {
try {
sleep(record)
} catch (err) {
console.log('Error inside catch block1', err)
throw err
}
})
).then(data => {
console.log('Resolved', data)
})
.catch(err => {
console.log('Error inside catch block2', err)
throw err
});
} catch (err) {
console.log('Error inside catch block3', err)
}
}
test();
使用 catch block 后为什么仍然收到未处理的拒绝。任何帮助表示赞赏。但如果我使用异步等待不会得到未处理的拒绝。
最佳答案
您的代码存在多个问题,让我们逐一解决这些问题:
首先
当您映射 lists
数组时,您永远不会返回从 sleep()
函数获得的 promise 。这意味着您提供给 Promise.all()
的是一个填充有 undefined
的数组。 Promise.all()
将非 Promise 的值视为已解决的 Promise,因此无论 sleep()
创建的 Promise 是解决还是拒绝,您的 Promise.all()
都将始终得到解决。这也意味着没有任何东西可以捕获来自 sleep()
的被拒绝的 Promise,这就是您的脚本当前收到未处理的 Promise 拒绝的原因。
您可以通过使用 return sleep(record)
正确返回 promise 来解决此问题。但这还不足以消除所有未处理的 promise 拒绝,所以让我们继续......
其次
您已将对 sleep()
的调用包装在 try-catch
block 中。除非您使用 async-await
,否则 try-catch
block 将不会捕获被拒绝的 Promise。在这种情况下,它只会捕获创建 Promise 时抛出的错误。如果这是您的意图,那就没问题,但如果您的意图是捕获被拒绝的 promise ,那么它就行不通。
第三
您已将 catch()
处理程序附加到 Promise.all()
中。与前面提到的 try-catch 不同,它实际上会处理任何被拒绝的 promise 。但是,您在此处理程序中重新抛出错误,这意味着 promise 链仍将被拒绝。您已将 Promise.all()
包装在另一个 try-catch
block 中,但如上所述,这不会捕获被拒绝的 Promise,因此仍然被拒绝的 Promise 最终将无法处理。
在这种情况下,您不应该在最后一个 catch()
处理程序中重新抛出错误,因为我在这里看不到这样做的任何意义。如果您出于某种原因需要重新抛出它,则需要在链中稍后添加另一个 catch()
处理程序。
关于node.js - Promise.all 遭到未处理的拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56336280/