仅当 Promise.all 中的所有 API 调用都失败时才抛出错误

问题描述 投票:0回答:4

在启动 Express 服务器 JS 之前,我想进行三个 API 调用。如果其中任何一个失败,我只想记录一个错误,但如果三个都失败,我想抛出一个错误并阻止服务器启动。

我已经看到我可以使用

Promise.all
,但我不确定如果失败了如何处理这种情况。使用下面的代码如果任何失败都会抛出错误。如何限制这种情况仅在所有调用失败时才发生?

const fetchNames = async () => {
    try {
      await Promise.all([
        axios.get("./one.json"),
        axios.get("./two.json"),
        axios.get("./three.json")
      ]);
    } catch {
      throw Error("Promise failed");
    }
  };
javascript ecmascript-6 promise
4个回答
3
投票

如果您不需要履行值,或者只需要其中的任何

Promise.any
将适用于此用例 - 仅当所有 Promise 都拒绝时它才会拒绝。

const firstResolveValue = await Promise.any([
        axios.get("./one.json"),
        axios.get("./two.json"),
        axios.get("./three.json")
]);

如果您需要恰好满足的 Promise 的所有结果值,请使用

Promise.allSettled

const settledResults = await Promise.allSettled([
    axios.get("./one.json"),
    axios.get("./two.json"),
    axios.get("./three.json")
]);
const fulfilledResults = settledResults.filter(result => result.status === 'fulfilled');
if (!fulfilledResults.length) {
    throw new Error();
} else {
    // do stuff with fulfilledResults
}

1
投票

如果您只需要任何结果,

Promise.any
将适用于此用例 - 仅当所有承诺都拒绝时它才会拒绝。

const value = await Promise.any([
    axios.get("./one.json").catch(err => { console.log(err); throw err; }),
    axios.get("./two.json").catch(err => { console.log(err); throw err; }),
    axios.get("./three.json").catch(err => { console.log(err); throw err; }),
]);

如果您需要恰好履行的承诺的所有结果值,请使用

Promise.allSettled

const results = await Promise.allSettled([
    axios.get("./one.json"),
    axios.get("./two.json"),
    axios.get("./three.json"),
]);
const values = [], errors = [];
for (const result of results) {
    if (result.status === 'fulfilled') {
        values.push(result.value);
    } else { // result.status === 'rejected'
        errors.push(result.reason);
    }
}
if (!values.length) {
    throw new AggregateError(errors);
} else {
    for (const err of errors) {
        console.log(err);
    }
    // do stuff with values
}

0
投票

请帮我修复 ambari 中的此错误:启动所有服务 API 调用失败。


-1
投票

如果我理解正确的话,如果其中任何一个有效,您实际上不想执行

catch(e){...}
,对吗?那么你可以这样做:

const fetchNames = async () => {
    try {
      await Promise.all([
        axios.get("./one.json").catch(e => console.log(`one failed`, e)),
        axios.get("./two.json").catch(e => console.log(`two failed`, e)),
        axios.get("./three.json").catch(e => console.log(`three failed`, e))
      ]);
    } catch {
      throw Error("Promise failed");
    }
  };

上面的问题是,如果全部失败,则不会抛出错误。如果您也对此感兴趣,那么类似的事情应该有效:

const fetchNames = async () => {
    try {
      let success = false;
      await Promise.all([
        axios.get("./one.json").then( () => success = true).catch(e => console.log(`one failed`, e)),
        axios.get("./two.json").then( () => success = true).catch(e => console.log(`two failed`, e)),
        axios.get("./three.json").then( () => success = true).catch(e => console.log(`three failed`, e))
      ]);
    if (!success) throw new Error(`No successful promises`);
    } catch {
      throw Error("Promise failed");
    }
  };
© www.soinside.com 2019 - 2024. All rights reserved.