如何处理promise.all拒绝三个承诺中的一个承诺? 使用Promise.allSettled() 更多信息

问题描述

我有一个特殊的情况,在Promise.all中有两个诺言同时运行。 但其中一项承诺需要花费很长时间,因此我没有得到任何结果。 除了一个承诺,其他承诺正在解决。 我想用很长的时间(例如:如果超过60秒)拒绝一条错误消息的承诺,以便我可以从Promise.all得到答复。

例如:

const [client1Prices,client2Prices] = await Promise.all([
      this.client1.getSimulationPrices({
        hourPay: journey.hourPay,jobType: journey.jobType,salary: journey.salary,weeklyHours: journey.weeklyHours,}),this.client2.getSimulationPrices({   // takes more than 60 sec and i want to reject this promise
        hourPay: journey.hourPay,})
    ]);

this.client2.getSimulationPrices需要花费很多时间来解决,因此Promise.all没有给我任何结果。我想在60秒内拒绝,这样我就可以从Promise.all得到答复。

请提出如何处理这种情况?

解决方法

使用Promise.allSettled()

它返回ar对象数组,在所有给定的promise都已实现或被拒绝后解析。

数组中的每个对象都描述了每个诺言的结果。

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve,reject) => setTimeout(reject,100,'Prmoise 2'));
const promise3 = new Promise((resolve,reject) => setTimeout(resolve,200,'Promise 3'));

const promise4 = new Promise((resolve,'Promise 4'));

const promises = [promise1,promise2,promise3,promise4];

Promise.allSettled(promises).
then((results) => results.forEach((result) => console.log(result.status)));

// expected output:

// "fulfilled"
// "rejected"
// "fulfilled"
// "rejected"

更多信息

Promise.allSettled() - MDN


所有主流浏览器都支持。因此,您无需使用任何外部库甚至是polyfill。

,

您正在寻找Promise.allSettled()。与Promise.all()不同,如果任何承诺失败,它都不会抛出错误。相反,结果是一个对象,该对象可以是:

{
    status: 'fulfilled',value: return_value
}

如果没有错误,或者:

{
    status: 'rejected',reason: error_message
}

如果有错误。

MDN表示节点12.9.0及更高版本对此提供支持。如果您在没有它的环境中需要它,则在npm上有一个纯js实现:https://www.npmjs.com/package/promise.allsettled

请参阅:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled

,

您应该考虑使用Observable,因为它比较容易处理,但是您仍然可以使用promises。

您将要使用Promise.race()

Promise.race()方法返回一个诺言,该诺言一旦具有可迭代的实现或拒绝中的一个诺言,即带有该诺言的值或原因,即会实现或拒绝。

const timeoutPromise = new Promise((resolve,reject) => setTimeout(() => reject('TIMEOUT'),60000));
});
const [client1Prices,client2Prices] = await Promise.all([
      this.client1.getSimulationPrices({
        hourPay: journey.hourPay,jobType: journey.jobType,salary: journey.salary,weeklyHours: journey.weeklyHours,}),Promise.race([timeoutPromise,this.client2.getSimulationPrices({
        hourPay: journey.hourPay,})])
    ]);

您可以保证在60秒或更短的时间内恢复client2Prices。您可以检查该值以确定它是否超时或成功。如果您想吞下超时错误(没有使Promise.all()失败,则可以使超时resolve(而不是reject),或切换为使用Promise.allSettled() >

,

bluebird是一个出色的Promises库。 它具有timeout函数,在这里将非常有用。

const Promise = require('bluebird');

const [client1Prices,client2Prices] = await Promise.allSettled([
      this.client1.getSimulationPrices(...).timeout(60000),this.client2.getSimulationPrices(...).timeout(60000)
    ]);