我有一个promise数组,我用Promise.all(arrayOfPromises)来解析它;

我继续承诺链。大概是这样的

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语句来处理一个单独的promise,以防它出错,但是当我尝试时,promise。all返回它找到的第一个错误(忽略其余的错误),然后我就不能从数组中的其余承诺(没有错误)中获得数据。

我试过做一些像…

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();
});

但这并不能解决问题。

谢谢!

--

编辑:

下面的答案是完全正确的,代码被破坏是由于其他原因。如果有人感兴趣,这是我最终得出的解决方案……

节点快速服务器链

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调用(路由。异步调用)

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

把。catch作为承诺。在.then之前的所有内容似乎都用于从原始的promise中捕获任何错误,但随后将整个数组返回到下一个.then

谢谢!


当前回答

使用Async await -

这里一个异步函数func1返回一个解析值,func2抛出一个错误并返回null,在这种情况下,我们可以按照自己的想法处理它并相应地返回。

const callingFunction  = async () => {
    const manyPromises = await Promise.all([func1(), func2()]);
    console.log(manyPromises);
}


const func1 = async () => {
    return 'func1'
}

const func2 = async () => {
    try {
        let x;
        if (!x) throw "x value not present"
    } catch(err) {
       return null
    }
}

callingFunction();

输出是- ['func1', null]

其他回答

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

一些图书馆有一种叫做承诺的东西。当,我理解它会等待数组中的所有承诺解决或拒绝,但我不熟悉它,它不在ES6中。

你的代码

我同意这里其他人的看法,您的修复应该有效。它应该使用一个包含成功值和错误对象的混合数组进行解析。在成功路径中传递错误对象是不寻常的,但假设您的代码期望它们,我认为这没有问题。

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

我冒昧地从您的示例中提出了“现有链”,并用catch终止了该链。这可能不适合你,但对于阅读这篇文章的人来说,总是返回或终止链是很重要的,否则潜在的错误,甚至是编码错误,将被隐藏(这就是我怀疑在这里发生的事情):

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
});

您需要知道如何识别结果中的错误。如果您没有标准的预期错误,我建议您对catch块中的每个错误运行转换,使其在结果中可识别。

try {
  let resArray = await Promise.all(
    state.routes.map(route => route.handler.promiseHandler().catch(e => e))
  );

  // in catch(e => e) you can transform your error to a type or object
  // that makes it easier for you to identify whats an error in resArray
  // e.g. if you expect your err objects to have e.type, you can filter
  // all errors in the array eg
  // let errResponse = resArray.filter(d => d && d.type === '<expected type>')
  // let notNullResponse = resArray.filter(d => d)

  } catch (err) {
    // code related errors
  }

这不是记录错误日志的最佳方法,但是您总是可以为promiseAll设置一个数组,并将结果存储到新变量中。

如果你使用graphQL,你需要后处理响应,无论如何,如果它没有找到正确的引用,它将崩溃应用程序,缩小问题所在

const results = await Promise.all([
  this.props.client.query({
    query: GET_SPECIAL_DATES,
  }),
  this.props.client.query({
    query: GET_SPECIAL_DATE_TYPES,
  }),
  this.props.client.query({
    query: GET_ORDER_DATES,
  }),
]).catch(e=>console.log(e,"error"));
const specialDates = results[0].data.specialDates;
const specialDateTypes = results[1].data.specialDateTypes;
const orderDates = results[2].data.orders;

我们可以在单个承诺级别处理拒绝,所以当我们在结果数组中获得结果时,被拒绝的数组索引将是未定义的。我们可以根据需要处理这种情况,并使用剩余的结果。

这里我拒绝了第一个承诺,所以它没有定义,但是我们可以使用第二个承诺的结果,它在索引1处。

const manyPromises = Promise.all([func1(), func2()])。然后(result => { console.log(结果[0]);/ /定义 console.log(结果[1]);/ / func2 }); 函数func1() { return new Promise((res, rej) => rej('func1'))。Catch (err => { Console.log('错误处理',err); }); } 函数func2() { return new Promise((res, rej) => setTimeout(() => res('func2'), 500)); }

ES2020为Promise类型引入了新的方法:Promise. allsettle()。

的承诺。当所有输入承诺都已解决时,allsettle会给你一个信号,这意味着它们要么被满足,要么被拒绝。这在不关心承诺状态的情况下很有用,您只想知道工作何时完成,而不管它是否成功。

异步函数(){ Const promises = [ Fetch ('/api.stackexchange.com/2.2'), //成功 Fetch ('/this-will-fail') //失败 ]; const result = await promise . allsettle (promises); console.log(结果。Map (promise => promise.status)); // [' completed ', 'rejected'] }

详见v8博客文章。