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

only throw error if all API calls in Promise.all fail

在启动快速服务器 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");
    }
  };

如果您不需要 fulfillment 值,或者只需要其中的 anyPromise.any 将适用于此用例 - 只有在以下情况下才会拒绝所有承诺都拒绝。

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
}

如果我没理解错的话,您实际上有兴趣不执行 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");
    }
  };

如果您只需要 any 个结果,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
}