解决承诺时如何保持顺序(Promise.allSettled)?

How to keep the order when resolving promises (Promise.allSettled)?

此代码对 cases 中的每个案例 ID 执行 GET 请求。然后它会验证每个案例是否已满或有错误。

let cases = [ /* array of case objects having the property CaseId */ ];
let promises = [];

// fetch all cases first
cases.forEach(c => promises.push(CaseSource.get(c.CaseId)));

// validate each case
Promise.allSettled(promises).then((results) => {
  results.forEach((promise) => {
    if (promise.status === "fulfilled") {
      let fetchedCase = promise.value;
      let caseSize = fetchedCase.Evidences.length;
      if (caseSize + 1 > MAX_CASE_SIZE) {
        fullCases.push(fetchedCase.Title);
      } else {
        validCases.push(fetchedCase);
      }
    } else {
      let error = promise.reason;
      this.loadCaseError(ApiException.parse<IExceptionModel>(error), /* need to use c.CaseId here... */);
    }
  }); this.loadAllCases(fullCases, validCases);
});

我希望能够获得有错误的案例的案例 ID。但是,它不是 promise.reason 中的 属性,我无法添加它。这些 ID 在原始 cases 数组中。

我考虑过跟踪 promise 的索引,但是,我认为 promise 不会以与执行 GET 请求相同的顺序在 promises 数组中解析(不保证因为异步)。

有什么方法可以保留订单吗?

Promise.all/allSettled 的结果严格按插入顺序排列,因此您应该能够通过其索引轻松访问源代码:

Promise.allSettled(promises).then((results) => {
  results.forEach((result, INDEX) => {
    if (result.status === "fulfilled") {
      ....
    } else {
      let error = promise.reason;
      whatever(error, cases[INDEX]);
    }

对于更一般的情况,在 promises 结算后输入不可用或它们的顺序未知,您可以使用 all 和包装器作为 allSettled 的更灵活的替代方案:

Promise.all(
    INPUTS.map(input =>
        FUNC(input)
            .then(result  => ({status: 'fulfilled', result, input}))
            .catch(reason => ({status: 'rejected', reason, input}))
    ))

以便可以将任意负载添加到 result 对象。