提问者:小点点

处理允诺中的错误。所有


我正在用解析一个许诺数组

我接着继续承诺链。看起来像这样

existingPromiseChain = existingPromiseChain.then(function() {
  var arrayOfPromises = state.routes.map(function(route){
    return route.handler.promiseHandler();
  });
  return Promise.all(arrayOfPromises)
});

existingPromiseChain = existingPromiseChain.then(function(arrayResolved) {
  // do stuff with my array of resolved promises, eventually ending with a res.send();
});

我想添加一个catch语句来处理单个承诺,以防它出错,但是当我尝试时,返回它找到的第一个错误(忽略rest),然后我无法从数组中的其余承诺(没有出错)获得数据。

我试过做一些类似的事情…

existingPromiseChain = existingPromiseChain.then(function() {
      var arrayOfPromises = state.routes.map(function(route){
        return route.handler.promiseHandler()
          .then(function(data) {
             return data;
          })
          .catch(function(err) {
             return err
          });
      });
      return Promise.all(arrayOfPromises)
    });

existingPromiseChain = existingPromiseChain.then(function(arrayResolved) {
      // do stuff with my array of resolved promises, eventually ending with a res.send();
});

但这并不能解决问题。

谢啦!

--

编辑:

下面所说的答案是完全正确的,代码是由于其他原因而被打破的。如果有人感兴趣,这就是我的解决方案。

Node Express服务器链

serverSidePromiseChain
    .then(function(AppRouter) {
        var arrayOfPromises = state.routes.map(function(route) {
            return route.async();
        });
        Promise.all(arrayOfPromises)
            .catch(function(err) {
                // log that I have an error, return the entire array;
                console.log('A promise failed to resolve', err);
                return arrayOfPromises;
            })
            .then(function(arrayOfPromises) {
                // full array of resolved promises;
            })
    };

API调用(Route.Async调用)

return async()
    .then(function(result) {
        // dispatch a success
        return result;
    })
    .catch(function(err) {
        // dispatch a failure and throw error
        throw err;
    });

放在之前似乎起到了从原始承诺中捕获任何错误的作用,但随后将整个数组返回到下一个

谢啦!


共3个答案

匿名用户

是全部或无。一旦数组中的所有承诺解决,它就会解决,或者一旦其中一个承诺拒绝,它就会拒绝。换句话说,它要么用所有已解析值的数组进行解析,要么用单个错误进行拒绝。

有些库有一个名为的东西,我理解它会等待数组中的所有承诺来解析或拒绝,但我不熟悉它,而且ES6中没有它。

您的代码

我同意这里其他人的看法,你的办法应该行得通。它应该使用一个数组进行解析,该数组可能混合包含成功值和错误对象。在success-path中传递错误对象是不常见的,但假设您的代码需要它们,我认为这没有问题。

我能想到为什么它会“不解决”的唯一原因是,它在代码中失败了,而您没有看到任何错误消息的原因是,这个承诺链没有终止于最终捕获(就您给我们显示的情况而言)。

我已经冒昧地从你的例子中分解出了“现有的链”,并用一个捕获终止了这个链。这可能不适合您,但对于阅读本文的人来说,总是返回或终止链是很重要的,否则潜在的错误,甚至编码错误,将被隐藏(我怀疑这里发生了这种情况):

Promise.all(state.routes.map(function(route) {
  return route.handler.promiseHandler().catch(function(err) {
    return err;
  });
}))
.then(function(arrayOfValuesOrErrors) {
  // handling of my array containing values and/or errors. 
})
.catch(function(err) {
  console.log(err.message); // some coding error in handling happened
});

匿名用户

新答案

const results = await Promise.all(promises.map(p => p.catch(e => e)));
const validResults = results.filter(result => !(result instanceof Error));

未来承诺API

    的默认定义

匿名用户

ES2020为承诺类型引入了新的方法:Promise.allSettleds在所有输入承诺都已结算时给出一个信号,这意味着它们已经兑现或被拒绝。如果您不关心承诺的状态,只想知道工作何时完成,而不管它是否成功,那么这是很有用的。

const promises = [
  fetch('/api-call-1'),
  fetch('/api-call-2'),
  fetch('/api-call-3'),
];
// Imagine some of these requests fail, and some succeed.

const result = await Promise.allSettled(promises);
console.log(result.map(x=>x.status));
// ['fulfilled', 'fulfilled', 'rejected']

阅读更多v8博客文章https://v8.dev/features/promise-combinators