
Saad
Gibt es Probleme bei der Nutzung async
/await
in einem forEach
Schleife? Ich versuche, eine Reihe von Dateien zu durchlaufen und await
auf den Inhalt jeder Datei.
import fs from 'fs-promise'
async function printFiles () {
const files = await getFilePaths() // Assume this works fine
files.forEach(async (file) => {
const contents = await fs.readFile(file, 'utf8')
console.log(contents)
})
}
printFiles()
Dieser Code funktioniert, aber könnte damit etwas schief gehen? Ich hatte jemanden, der mir sagte, dass Sie nicht verwenden sollten async
/await
in einer übergeordneten Funktion wie dieser, also wollte ich nur fragen, ob es ein Problem damit gibt.

Francisco Mateo
Mit ES2018 können Sie alle oben genannten Antworten erheblich vereinfachen:
async function printFiles () {
const files = await getFilePaths()
for await (const contents of files.map(file => fs.readFile(file, 'utf8'))) {
console.log(contents)
}
}
Siehe Spezifikation: Vorschlag-Async-Iteration
2018-09-10: Diese Antwort hat in letzter Zeit viel Aufmerksamkeit erregt, siehe bitte Blogbeitrag von Axel Rauschmayer für weitere Informationen zur asynchronen Iteration.

Antonio Wal
Die p-Iteration Das Modul auf npm implementiert die Array-Iterationsmethoden, sodass sie auf sehr einfache Weise mit async/await verwendet werden können.
Ein Beispiel mit Ihrem Fall:
const { forEach } = require('p-iteration');
const fs = require('fs-promise');
(async function printFiles () {
const files = await getFilePaths();
await forEach(files, async (file) => {
const contents = await fs.readFile(file, 'utf8');
console.log(contents);
});
})();

mikemaccana
Hier sind einige forEachAsync
Prototypen. Beachten Sie, dass Sie müssen await
Ihnen:
Array.prototype.forEachAsync = async function (fn) {
for (let t of this) { await fn
}
Array.prototype.forEachAsyncParallel = async function (fn) {
await Promise.all(this.map(fn));
}
Notiz Während Sie dies in Ihren eigenen Code aufnehmen können, sollten Sie dies nicht in Bibliotheken aufnehmen, die Sie an andere verteilen (um deren Globals nicht zu verschmutzen).

krupesch Anadkat
Ein Bild sagt mehr als 1000 Worte – Nur für sequenzielle Annäherung
Hintergrund : Ich war letzte Nacht in einer ähnlichen Situation. Ich habe die async-Funktion als foreach-Argument verwendet. Das Ergebnis war nicht vorhersehbar. Als ich meinen Code dreimal getestet habe, lief er zweimal ohne Probleme und schlug einmal fehl. (etwas Komisches)
Endlich habe ich mich umgesehen und einige Scratchpad-Tests durchgeführt.
Szenario 1 – Wie unsequenziell kann es mit async in foreach werden

const getPromise = (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`Promise resolved for ${time}s`)
}, time)
})
}
const main = async () => {
const myPromiseArray = [getPromise(1000), getPromise(500), getPromise(3000)]
console.log('Before For Each Loop')
myPromiseArray.forEach(async (element, index) => {
let result = await element;
console.log(result);
})
console.log('After For Each Loop')
}
main();
Szenario 2 – Verwenden for - of
Schleife wie oben von @Bergi vorgeschlagen

const getPromise = (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`Promise resolved for ${time}s`)
}, time)
})
}
const main = async () => {
const myPromiseArray = [getPromise(1000), getPromise(500), getPromise(3000)]
console.log('Before For Each Loop')
// AVOID USING THIS
// myPromiseArray.forEach(async (element, index) => {
// let result = await element;
// console.log(result);
// })
// This works well
for (const element of myPromiseArray) {
let result = await element;
console.log(result)
}
console.log('After For Each Loop')
}
main();
Wenn du wie ich ein kleiner Oldschooler bist, könntest du einfach die klassische for-Schleife verwenden, das geht auch 🙂
const getPromise = (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`Promise resolved for ${time}s`)
}, time)
})
}
const main = async () => {
const myPromiseArray = [getPromise(1000), getPromise(500), getPromise(3000)]
console.log('Before For Each Loop')
// AVOID USING THIS
// myPromiseArray.forEach(async (element, index) => {
// let result = await element;
// console.log(result);
// })
// This works well too - the classic for loop :)
for (let i = 0; i < myPromiseArray.length; i++) {
const result = await myPromiseArray[i];
console.log(result);
}
console.log('After For Each Loop')
}
main();
Ich hoffe, das hilft jemandem, guten Tag, Prost!
9868900cookie-checkVerwenden von async/await mit einer forEach-Schleifeyes
warum rufst du an
printFiles
eine Funktion höherer Ordnung, wenn sie keine Funktion als Argument erhält oder keine Funktion als Ausgabe zurückgibt?– elirandav
9. August 2020 um 17:34 Uhr
@KernelMode Die
forEach
Methode ist hier die Funktion höherer Ordnung– Bergi
9. August 2020 um 18:58 Uhr