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

Fry*_*Pan 0 javascript asynchronous promise

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

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);
});
Run Code Online (Sandbox Code Playgroud)

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

我考虑过跟踪 Promise 的索引,但是,我认为 Promise 不会promises按照执行 GET 请求的顺序在数组中解析(由于异步,因此无法保证)。

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

geo*_*org 5

的结果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]);
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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