簡體   English   中英

Promise.all 與 foreach Promise

[英]Promise.all versus foreach Promise

我有一個 Angular 計算器應用程序,它計算一些按表格分組的結果( CalculatorResult )(如Excel 表格)。 假設我們有六張紙。

我有一個方法, calculateSheet ,它需要一些屬性,工作表名稱,並返回一些CalculatorResult[]

async calculateSheet(
       propertyValues: PropertyValue[],
       sheetTypeName: string): Promise<CalculatorResult[]>

計算所有六張工作表的方法calculateSheets應該計算六張工作表中的每一張,然后將結果的所有結果數組聚合到一個數組中(CalculatorResult 的六個數組應該成為一個)。

所以,我嘗試了兩種方法來聚合它,如下:

// define all promises to be calculated
const promises: (() => Promise<CalculatorResult[]>)[] = [this.selectedSheetTypeName, ...(sheets.value as Sheet[]).map((sheet: Sheet) => sheet.type.name)
  .filter((sheetTypeName: string) => sheetTypeName != this.selectedSheetTypeName)]
  .map((sheetTypeName: string) => this.calculateSheet.bind(this, propertyValues, sheetTypeName));

// now, await all results, and build a common array from 6 arrays(one per sheet) of results
let results: CalculatorResult[] = [];

// WHERE IS THE DIFFERENCE OF

// THIS ONE
const myValues = await Promise.all(promises);
console.log("All 6 sheets promises here bellow:");
console.log(myValues);


// VERSUS THIS ONE
for (const promise of promises) {
  let sheetResults = await promise();
  console.log("Sheet results:")
  console.log(sheetResults)
  results.push(...sheetResults);
  console.log("All results:")
  console.log(results)
}

在第一種情況下( myValues ),為什么我們有六個函數作為結果,而不是 CalculatorResults 數組?

在此處輸入圖像描述

TL;博士

根據經驗:

  • 如果您想並行執行所有內容並盡可能快地獲得結果,請使用Promise.all
  • 如果您想執行與上述相同的操作,但如果一個失敗則獲得所有承諾結果,請使用: allSettled或類似
  • 如果要按順序執行每個承諾,請使用for Promise

首先,在您的示例中, promises數組實際上是一個函數數組,您永遠不會執行它,這就是Promise.all返回所有 fns 的原因。 使固定:

const promises = ….map((sheetTypeName: string) => this.calculateSheet(propertyValues, sheetTypeName));

Promise.all

如果所有的承諾都成功了

  • 將等到所有承諾完成,並返回一組結果

如果任何承諾被拒絕

  • 無論 promise 何時被拒絕,也無論兩個或更多被拒絕,它都會返回一個被拒絕的 promise,其中包含第一個被拒絕的 promise 的錯誤。 一旦第一個錯誤被拋出,它就會發生。
  • 你永遠不知道哪個承諾是失敗的。 如果你想知道是什么promise生成的,這個錯誤應該包含一些額外的信息。
  • 如果兩個或多個 promise 失敗了,你永遠不會知道。 其他 Promise 的狀態如何是未知的,因為您只會收到發生的第一個錯誤。 當 Promise 被拒絕時,其他 Promise 可能無法完成。
  • 如果您想等待每個承諾都被解決/拒絕,您可以使用allSettled或類似的東西。

for promises

主要區別在於會按順序執行每個函數。 它將等待執行並完成第一個,然后執行第二個,依此類推。

此外,您控制流程,因此如果第一個失敗,您可以選擇繼續或不繼續,或者做什么。

順便說一句,我永遠不會使用 bind 來實現它,會直接在for中執行每個方法/函數

暫無
暫無

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

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