簡體   English   中英

等待Promise.all內部的諾言完成后再解決

[英]Wait for promises inside Promise.all to finish before resolving it

我有一個Promise.all,如果它不為null,則執行映射到數組輸入上的異步函數,然后將數據解析為先前定義的Promise:

Promise.all((inputs || []).map(input => {
  return new Promise((resolve, reject) => {
    someAsyncFunc(input)
    .then(intermediateOutput => {
      someOtherAsyncFunc(intermediateOutput )
      .then(output => {
        return Promise.resolve(output )
      })
      .catch(reason=> {
        return Promise.reject(reason)
      })
    })
    .catch(reason => {
      return Promise.reject(reason);
    })
  })
  .then(outputs => {
    resolve(outputs)
  })
  .catch(reason => {
    reject(reason)
  })
}))

在someAsyncFunc完成工作之前,我只會得到空的輸出。 如何使Promise.all等待內部的諾言完成異步工作?

不只是

return Promise.all((inputs || []).map(input =>
 somePromiseFunc(input).then(someOtherPromiseFunc)
);

工作?

您第一次沒有使用Promise.all ,因為它接受了一組Promise.all作為輸入,而不是(resolve, reject) => { ... }

Promise.all將在基本承諾之一失敗后立即被拒絕,因此您無需嘗試在catch(error => reject(error)周圍做一些事情

例:

const somePromiseFunc = (input) => new Promise((resolve, reject) => {
  setTimeout(() => {
    if (input === 0) { reject(new Error('input is 0')); }
    resolve(input + 1);
  }, 1000);
});

const someOtherPromiseFunc = (intermediateOutput) => new Promise((resolve, reject) => {
  setTimeout(() => {
    if (intermediateOutput === 0) { reject(new Error('intermediateOutput is 0')); }
    resolve(intermediateOutput + 1);
  }, 1000);
});

const f = inputs => {
  const t0 = Date.now()
  return Promise.all((inputs || []).map(input => somePromiseFunc(input).then(someOtherPromiseFunc)))
    .then(res => console.log(`result: ${JSON.stringify(res)} (after ${Date.now() - t0}ms)`))
    .catch(e => console.log(`error: ${e} (after ${Date.now() - t0}ms)`));
};

f(null)
// result: [] (after 0ms)

f([1, 0])
// error: Error: input is 0 (after 1001ms)

f([1, -1])
// error: Error: intermediateOutput is 0 (after 2002ms)

f([1, 2])
// result: [3,4] (after 2002ms)

請參閱jfriend的評論。

someAsyncFuncsomeOtherAsyncFunc是正確返回promise的函數,例如return new Promise(/*...*/);

這是沒有用的:

.then(output => {
  return Promise.resolve(output )
})

閱讀Promise文檔

相同

.catch(reason=> {
  return Promise.reject(reason)
})

承諾已經在拒絕,您無需捉住並拒絕自己

確保Promise是可鏈接的,您需要返回Promise

// ...
return new Promise((resolve, reject) => {
  if(inputs == null)
    resolve([]);
  else {
    Promise.all(inputs.map(input => {
      return someAsyncFunc(input)
        .then(someOtherAsyncFunc)
    }))
      .then(resolve)
      .catch(reject)
  }
});

請注意,我寧願不對Promise.all進行內聯,它會增加視覺混亂:

return new Promise((resolve, reject) => {
  if(inputs == null)
    resolve([]);
  else {
    const myPromises = inputs.map(input => {
      return someAsyncFunc(input)
        .then(someOtherAsyncFunc)
    });
    Promise.all(myPromises)
      .then(resolve)
      .catch(reject)
  }
});

如果您犯了其他錯誤,它可能仍然會失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM