JavaScript Async forEach
Im heutigen Beitrag schauen wir uns an, ob wir async
in der forEach
-Schleife von JavaScript verwenden können. Was sind die Alternativen?
Asynchron forEach
in JavaScript
Asynchrone Programmierung ist für Array.prototype.forEach
nicht vorgesehen. Es ist für async-await
ebenso ungeeignet wie für Promises.
const employees = await this.getEmployees();
// BAD
await employees.forEach(async (employee) => {
await giveBonusToEmployee(employee);
});
await sendEmail('All bonuses sent');
Hier sind einige der Probleme damit:
- Die von der Iteratorfunktion zurückgegebenen Promises werden nicht behandelt; daher wird es nicht bemerkt, wenn einer von ihnen einen Fehler macht. Wenn auf Node 10 kein
unhandledrejection
-Listener registriert ist, stürzt der Prozess ab! - Alle Boni werden gleichzeitig und nicht nacheinander verteilt, da
forEach
nicht darauf wartet, dass jedes Versprechen einzeln erfüllt wird. Infolgedessen endet die Schleife, bevor alle Boni ausgegeben wurden. - Als Ergebnis sendet
sendEmail()
die E-Mail, bevor einer der Boni vollständig ausgegeben wurde. Vielleicht wird keiner ausgegeben; sie könnten alle Fehler werfen!
Unten ist die Lösung, die wir dafür implementieren können:
- Verarbeiten Sie jeden Bonus der Reihe nach. Sie können die Konstruktion
for...of
verwenden, da JavaScriptasync-await
unterstützt.
for (const employee of employees) {
await giveBonusToEmployee(employee);
}
Bevor zum nächsten Bonus übergegangen wird, wartet diese Schleife auf die Ausgabe des vorherigen. Obwohl es ausführlicher wäre, als wir brauchen, könnten Sie in dieser Situation auch ein typisches for(...;...;...)
verwenden.
- Verarbeiten Sie alle Boni parallel.
await Promise.all(employees.map(async (employee) => {
await giveBonusToEmployee(employee);
}));
Es kann schneller sein, alle Mitarbeiter gleichzeitig zu analysieren, wenn die Reihenfolge keine Rolle spielt. Dadurch werden alle Boni auf einmal ausgegeben, aber es wird erst sendEmail()
gesendet, wenn alle Boni gesendet wurden.
Die Schleifen for
und while
arbeiten natürlich mit async-await
, weil sie im ursprünglichen Funktionskörper geschrieben sind. Wenn Sie jedoch eine andere Funktion aufrufen, kann async-await
nur verwendet werden, wenn die aufgerufene Funktion ein Versprechen zurückgibt und dieses Versprechen verarbeitet.
Da sowohl .reduce()
als auch .map()
ein Versprechen oder eine Reihe von Versprechen erzeugen, die wir erwarten
können, können wir sie verwenden.
Die meisten Array-Methoden geben jedoch keine Zusagen zurück oder lassen zu, dass Zusagen von einem Aufruf an einen anderen weitergegeben werden, sodass sie nicht asynchron verwendet werden können. Daher kann innerhalb eines Arrays kein asynchroner Code verwendet werden, beispielsweise array.some()
oder array.filter()
.
Shraddha is a JavaScript nerd that utilises it for everything from experimenting to assisting individuals and businesses with day-to-day operations and business growth. She is a writer, chef, and computer programmer. As a senior MEAN/MERN stack developer and project manager with more than 4 years of experience in this sector, she now handles multiple projects. She has been producing technical writing for at least a year and a half. She enjoys coming up with fresh, innovative ideas.
LinkedIn