首页 > 解决方案 > 稍后以编程方式将捕获添加到多个承诺

问题描述

我有一些做同样事情的承诺,我希望以catch编程方式向它们添加一条语句,然后在它们上运行 Promise.all。我有一些实现这一目标的想法,但它一直在我面前爆炸。

let promises = [
  Promise.reject('derp'), // Naïve test
  new Promise((resolve, reject) => { // Assumed this ran out of main loop
    reject('whayyy')
  }),
  new Promise((resolve, reject) => { // really assumed this ran out of main loop
    process.nextTick(() => reject('nooooon'))
  })
]

//fails
for(let promise of promises){
  promise.catch((err) => { return 'fixed programatically'} )
}
Promise.all(promises).then((things) => {
  console.log("Expect to make it here with no problems")
  console.log(things) 
})

我不断得到这三个承诺:

(node:25148) UnhandledPromiseRejectionWarning: derp|whayy|nooooon
(node:25148) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

有谁知道如何正确地做到这一点?

编辑:我不知道为什么,我重新运行了原始代码,不再出现任何错误。:(

标签: javascriptnode.jspromise

解决方案


您需要将数组中的每个 Promise 替换为调用 catch 的结果的新 Promise。否则,您仍然只有数组中的原始(被拒绝)承诺,然后Promise.all最终再次拒绝,并且由于您没有抓住这一点,您会收到未处理的承诺拒绝错误。

替换数组中的 promise 的最好方法可能是在整个数组上使用Array#map :

promises = promises.map( promise => 
  promise.catch((err) => { return 'fixed programatically'} )
);

完整代码(使用 setTimeout 使其可以在浏览器中运行):

let promises = [
  Promise.reject('derp'), // Naïve test
  new Promise((resolve, reject) => { // Assumed this ran out of main loop
    reject('whayyy')
  }),
  new Promise((resolve, reject) => { // really assumed this ran out of main loop
    setTimeout(() => reject('nooooon'),0)
  }),
  Promise.resolve( 'success case, doesn\'t need fixing' ),
]

promises = promises.map( promise => 
  promise.catch((err) => { return 'fixed programatically'} )
);

Promise.all(promises).then((things) => {
  console.log("Expect to make it here with no problems")
  console.log(things) 
})


推荐阅读