有承诺错误时,有没有办法检查promise.all中每个Promise中的错误

时间:2018-02-27 17:51:57

标签: javascript promise

我有一个承诺数组,每个承诺执行一个代码,可能会出现javascript错误并破坏脚本。我需要检查每个承诺并发现任何错误。问题是promise中有超时函数。反正有没有解决这个问题?

示例代码:

function apiRequest(url,customError) {
  return new Promise(function (resolve, reject) {
    if(customError) {
        setTimeout(() => {
            //Force error
            var ar = url.asdasd.eadasd;
            ar = ar.split('123')
        },3000)
    }
    if (url) {
        return resolve(url);
    } else {
        return reject('apiRequest failed!');
    }
})
.catch(function(err){
    return 'error on javascript code';
});
}
var p1 = apiRequest('urlOne',true);
var p2 = apiRequest(false,false);
var p3 = apiRequest('urlThree');

Promise.all([p1, p2, p3])
   .then(function(res){
       console.log('Promise.all', res);
   }, error => {
       console.log('Error on reject')
   })
   .catch(function(err){
       console.error('err', err);
   });

结果:

  Promise.all [ 'urlOne', 'error on javascript code', 'urlThree' ]
  var ar = url.asdasd.eadasd;
  TypeError: Cannot read property 'eadasd' of undefined

如果每个promise中都有错误,我的代码可以捕获它,但如果有超时并且在promise完成后发生错误我无法捕获它并且我的代码中断了,无论如何都要捕获此错误?

1 个答案:

答案 0 :(得分:0)

  

当存在promise错误时,有没有办法检查promise.all中每个Promise中的错误?

按照设计,当你传递的所有承诺已经解决时,Promise.all()会解决,或者当它中的任何一个承诺拒绝时,它会拒绝。根据设计,它不会等待所有承诺解决或拒绝,然后给出所有结果,无论它们是已解决还是拒绝。

这样的功能通常被命名为Promise.settle(),你可以通过向.catch()传递的每个承诺添加Promise.all()处理程序来轻松构建这种类型的功能,而不是拒绝,它结算,但有一个值,你可以稍后告诉它实际上被拒绝。

您可以在此答案中看到.settle()类型功能的几种不同实现:

ES6 Promise.all() error handle - Is .settle() needed?

  

如果每个promise中都有错误,我的代码可以捕获它,但如果有超时并且在promise完成后发生错误我无法捕获它并且我的代码中断了,无论如何都要捕获此错误?

您构建setTimeout()的方式,它根本没有与它所在的承诺相关联。如果你想连接它们,那么你必须等到超时结束后再解决,然后才能知道你是否应该解决或拒绝。

由于您在setTimeout()中显示的代码看起来像伪代码(实际上还没有做任何事情),因此我们很难确切地看到{ {1}}确切地知道你想要达到的目标,因此是一个好的建议。

关于使用setTimeout()作为承诺链的一部分的答案可能是相关的:

using setTimeout on promise chain

在这种情况下,计时器被插入到promise链中,以便在它之前和之后对事物进行排序。正如您现在所展示的那样,它是一个完全独立的并行执行路径,与您的承诺链完全无关。

如果你在setTimeout()尝试做的只是在你的api请求在定时器触发之前没有返回时调用超时,那么你可以通过调用{{1}来实现它。在setTimeout()内。如果api请求已经完成且已经调用reject(),那么调用setTimeout()将不会执行任何操作。如果api请求尚未完成,则调用resolve()将拒绝主机承诺。