Laut MDN gibt for await...of
es zwei Anwendungsfälle:
Die
for await...of
Anweisung erstellt eine Schleife, die sowohl über asynchrone iterierbare Objekte als auch über synchronisierte iterierbare Objekte iteriert.
Ersteres war mir vorher bekannt: asynchrone iterables using Symbol.asyncIterator
. Aber ich interessiere mich jetzt für Letzteres: synchrone Iterables.
Der folgende Code iteriert über eine synchrone Iterable - eine Reihe von Versprechungen. Es scheint den Fortschritt bei der Erfüllung jedes Versprechens zu blockieren.
async function asyncFunction() {
try {
const happy = new Promise((resolve)=>setTimeout(()=>resolve('happy'), 1000))
const sad = new Promise((_,reject)=>setTimeout(()=>reject('sad')))
const promises = [happy, sad]
for await(const item of promises) {
console.log(item)
}
} catch (err) {
console.log(`an error occurred:`, err)
}
}
asyncFunction() // "happy, an error occurred: sad" (printed in quick succession, after about 5 seconds)
Das Verhalten scheint so zu sein, als würde man nach der unten gezeigten Logik nacheinander auf jedes Versprechen warten. Ist diese Behauptung richtig?
Ich frage , weil dieses Muster von Code eine implizite Ablehnung Draht-up pitfall hat , dass Promise.all
und zu Promise.allSettled
vermeiden, und es scheint mir seltsam , dass dieses Muster explizit von der Sprache unterstützt werden würde.
quelle
for await... of
mit synchronen Iterablen korrekt, und wenn ja, spielt es eine Rolle, dass dieses Muster unbehandelte Ablehnungsfehler ausgeben kann?Antworten:
Ja, es ist seltsam und du solltest das nicht tun. Wiederholen Sie keine Arrays von Versprechungen, es führt genau zu dem von Ihnen erwähnten Problem der unbehandelten Ablehnung .
Warum wird dies in der Sprache unterstützt? Fortsetzung der schlampigen Versprechenssemantik.
Die genaue Begründung finden Sie in diesem Kommentar zu diesem Thema des Vorschlags :
quelle
unhandledrejection
Ereignisse?window.addEventListener('unhandledrejection',...
Kurz gesagt: Es ist die einzige Instanz, an die ich mich erinnern kann, diese Art der Fehleremission durch JavaScript. Ich bin jedoch mit ziemlicher Sicherheit falsch, dies zu denken. Schließlich: Ist die Emission dieses "Fehlers" jemals wirklich wichtig, außer dass eine unerwünschte Fehlermeldung in der Konsole angezeigt wird?Das
sad
Versprechen wird nicht seinawait
ed , wenn es ausfällt - das Code Bedürfnis wartet auf beenden ,happy
bevor sie beginnen können , auf wartensad
. Dassad
Versprechen scheitert, bevor eshappy
gelöst wird. (Promise.all
ist ein Tool, das für diesen Anwendungsfall besser geeignet ist)quelle
Promise.all
eine bessere Lösung ist, warum berücksichtigt die Sprache diese Syntax?for await...of
hätte leicht implementiert werden können, um einfach asynchrone Iterables aufzulisten. Aber sie sorgten dafür, dass synchrone Iterables aufgezählt wurden (aber mit einer (scheinbaren?) Falle). Warum?for await ... of
synchrone Iterables akzeptiert werden? Ich würde mir vorstellen, asynchrone Generatoren zu unterstützen, die unter bestimmten Bedingungen synchrone Elemente zurückgeben können.