I have an Angular calculator application that calculates some results (CalculatorResult) grouped in sheets (like Excel ones). Say we have some six sheets.
I have a method, calculateSheet, that takes some properties, the sheet name, and returns some CalculatorResult[]:
async calculateSheet(
propertyValues: PropertyValue[],
sheetTypeName: string): Promise<CalculatorResult[]>
The method calculateSheets that calculates all six sheets,
should calculate each of the six sheets, and then aggregate all resulting arrays of the result in a single array (six arrays of CalculatorResult should become one).
So, I tried two methods to aggregate it, below:
// 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)
}
In the first case (myValues), why do we have six functions as the result, instead of the CalculatorResults array?
As rule of thumb:
Promise.allfor PromiseFirst of all, in your example the promises array is actually an array of functions, which you never execute, so that's why Promise.all returns all fns. Fix:
const promises = ….map((sheetTypeName: string) => this.calculateSheet(propertyValues, sheetTypeName));
Promise.all
If all the promises succeed:
If any promise is rejected:
for promises
The main difference is that will execute each function sequentially. It will wait to execute & finish the first one, to then execute the second one, and so on.
Also, you control the flow, so if the first one fails, you can choose to continue or not, or what to do.
BTW, I would never use bind to implement this, would execute every method/function directly in the for