Asynchrones DurchlaufenBevor wir die asynchrone Durchquerung erklären, erinnern wir uns noch einmal an die synchrone Durchquerung in ES6. Gemäß der Definition von ES6 besteht die Iteration im Wesentlichen aus drei Teilen: Iterierbar Schauen wir uns zunächst die Definition von Iterable an: Schnittstelle Iterable { [Symbol.iterator]() : Iterator; } Iterierbar bedeutet, dass dieses Objekt durchsuchbare Daten enthält und eine Factory-Methode implementieren muss, die einen Iterator generieren kann. Iterator Schnittstelle Iterator { nächstes() : IteratorErgebnis; } Iteratoren können aus Iterables konstruiert werden. Der Iterator ist ein Cursor-ähnliches Konzept, und auf das IteratorResult kann über „next“ zugegriffen werden. IteratorErgebnis IteratorResult sind die Daten, die bei jedem Aufruf der nächsten Methode erhalten werden. Schnittstelle IteratorResult { Wert: beliebig; fertig: Boolesch; } Neben einem Wert, der die abzurufenden Daten darstellt, verfügt IteratorResult auch über ein Done, das angibt, ob die Durchquerung abgeschlossen ist. Hier ist ein Beispiel für die Iteration über ein Array:
Das obige Beispiel durchläuft jedoch synchrone Daten. Wenn wir asynchrone Daten erhalten, z. B. vom http-Ende heruntergeladene Dateien, möchten wir die Datei zeilenweise durchlaufen. Da das Lesen einer Datenzeile ein asynchroner Vorgang ist, werden hierbei asynchrone Daten durchlaufen. Fügen Sie die asynchrone Dateilesemethode readLinesFromFile hinzu, dann ist die synchrone Durchlaufmethode nicht mehr auf die asynchrone anwendbar: //Nicht mehr anwendbar für (const line of readLinesFromFile(fileName)) { console.log(Zeile); } Sie fragen sich vielleicht, ob wir den Vorgang des asynchronen Lesens einer Zeile in einem Promise kapseln und es dann synchron durchlaufen können? Die Idee ist gut, aber in diesem Fall ist es unmöglich festzustellen, ob der asynchrone Vorgang abgeschlossen wurde. Daher ist diese Methode nicht durchführbar. Daher führte ES9 das Konzept der asynchronen Durchquerung ein: 1. Sie können Symbol.asyncIterator verwenden, um den Iterator in asynchronen Iterables zu erhalten. 2. Die next()-Methode des asynchronen Iterators gibt ein Promises-Objekt zurück, das IteratorResults enthält. Schauen wir uns also die API-Definition der asynchronen Durchquerung an: Schnittstelle AsyncIterable { [Symbol.asyncIterator]() : AsyncIterator; } Schnittstelle AsyncIterator { nächstes() : Versprechen<IteratorResult>; } Schnittstelle IteratorResult { Wert: beliebig; fertig: Boolesch; } Schauen wir uns eine asynchrone Durchquerungsanwendung an: asyncIterable = createAsyncIterable(['a', 'b']); const asyncIterator = asyncIterable[Symbol.asyncIterator](); asyncIterator.next() .then(iterResult1 => { console.log(iterResult1); // { Wert: 'a', fertig: false } gibt asyncIterator.next() zurück; }) .then(iterResult2 => { console.log(iterResult2); // { Wert: 'b', fertig: false } gibt asyncIterator.next() zurück; }) .then(iterResult3 => { console.log(iterResult3); // { Wert: undefiniert, fertig: true } }); Unter anderem konvertiert createAsyncIterable ein synchrones Iterable in ein asynchrones Iterable. Im nächsten Abschnitt erfahren Sie, wie es generiert wird. Hier konzentrieren wir uns hauptsächlich auf den Durchlaufvorgang von asyncIterator. Da ES8 den Async-Operator einführt, können wir den obigen Code auch mit der Async-Funktion umschreiben: asynchrone Funktion f() { asyncIterable = createAsyncIterable(['a', 'b']); const asyncIterator = asyncIterable[Symbol.asyncIterator](); console.log(warte auf asyncIterator.next()); // { Wert: 'a', fertig: false } console.log(warte auf asyncIterator.next()); // { Wert: 'b', fertig: false } console.log(warte auf asyncIterator.next()); // { Wert: undefiniert, fertig: true } } Asynchrone iterierbare DurchquerungVerwenden Sie for-of, um ein synchrones Iterable zu durchlaufen, und verwenden Sie for-await-of, um ein asynchrones Iterable zu durchlaufen. asynchrone Funktion f() { für warten (const x von createAsyncIterable(['a', 'b'])) { console.log(x); } } // Ausgabe: // A // B Beachten Sie, dass „await“ in einer asynchronen Funktion platziert werden muss. Wenn bei unserer asynchronen Durchquerung eine Ausnahme auftritt, können wir try catch in for-await-of verwenden, um die Ausnahme abzufangen: Funktion createRejectingIterable() { zurückkehren { [Symbol.asyncIterator]() { gib dies zurück; }, nächste() { return Promise.reject(neuer Fehler('Problem!')); }, }; } (asynchrone Funktion () { versuchen { für warten (const x von createRejectingIterable()) { console.log(x); } } fangen (e) { konsole.fehler(e); // Fehler: Problem! } })(); Das synchrone Iterable gibt synchrone Iteratoren zurück und die nächste Methode gibt {value, done} zurück. Wenn Sie for-await-of verwenden, werden synchrone Iteratoren in asynchrone Iteratoren umgewandelt. Der zurückgegebene Wert wird dann in ein Promise umgewandelt. Wenn der vom synchronen nächsten zurückgegebene Wert selbst ein Promise-Objekt ist, ist der asynchrone Rückgabewert immer noch dasselbe Promise. Das heißt, es wird Folgendes konvertiert: Iterable<Promise<T>> in AsyncIterable<T>, wie im folgenden Beispiel gezeigt: asynchrone Funktion main() { const syncIterable = [ Versprechen.lösen('a'), Versprechen.resolve('b'), ]; für warten (const x von syncIterable) { console.log(x); } } hauptsächlich(); // Ausgabe: // A // B Das obige Beispiel wandelt ein synchrones Promise in ein asynchrones Promise um. asynchrone Funktion main() { für warte (const x von ['a', 'b']) { console.log(x); } } hauptsächlich(); // Ausgabe: // C // D Das obige Beispiel konvertiert eine synchrone Konstante in ein Promise. Sie können sehen, dass die Ergebnisse dieselben sind. Asynchrone iterierbare GenerierungZurück zum obigen Beispiel: Wir verwenden createAsyncIterable(syncIterable), um syncIterable in AsyncIterable zu konvertieren. Sehen wir uns an, wie diese Methode implementiert wird: asynchrone Funktion* erstelleAsyncIterable(syncIterable) { für (const elem von syncIterable) { Ertragselement; } } Im obigen Code fügen wir vor einer normalen Generatorfunktion „async“ hinzu, was bedeutet, dass es sich um einen asynchronen Generator handelt. Bei gewöhnlichen Generatoren wird bei jedem Aufruf der nächsten Methode ein Objekt {value, done} zurückgegeben. Dieses Objekt ist eine Kapselung des Ertragswerts. Bei einem asynchronen Generator wird bei jedem Aufruf der nächsten Methode ein Promise-Objekt zurückgegeben, das das Objekt {value, done} enthält. Dieses Objekt ist eine Kapselung des Ertragswerts. Da ein Promise-Objekt zurückgegeben wird, müssen wir nicht warten, bis das Ergebnis der asynchronen Ausführung abgeschlossen ist, bevor wir die nächste Methode erneut aufrufen. Wir können ein Promise.all verwenden, um alle asynchronen Promise-Operationen gleichzeitig auszuführen: const asyncGenObj = createAsyncIterable(['a', 'b']); const [{Wert:v1},{Wert:v2}] = warte auf Promise.all([ asyncGenObj.next(), asyncGenObj.next() ]); console.log(v1, v2); // ab In createAsyncIterable erstellen wir ein asynchrones Iterable aus einem synchronen Iterable. Als nächstes schauen wir uns an, wie man aus einem asynchronen Iterable ein asynchrones Iterable erstellt. Aus dem vorherigen Abschnitt wissen wir, dass wir for-await-of verwenden können, um Daten aus einem asynchronen Iterable zu lesen. Daher können wir es folgendermaßen verwenden: asynchrone Funktion * Präfixzeilen (asyncIterable) { für warten (const Zeile von asyncIterable) { Ertrag '' > ' + Zeile; } } Im Generator-Artikel haben wir über das Aufrufen von Generatoren innerhalb von Generatoren gesprochen. Das heißt, in einem Produzenten wird ein anderer Generator mithilfe von yield* aufgerufen. Ebenso können wir dasselbe in einem Asynchrongenerator tun: asynchrone Funktion* gen1() { Ertrag 'a'; Ertrag 'b'; Rückgabe 2; } asynchrone Funktion* gen2() { const Ergebnis = Ertrag*gen1(); // Ergebnis === 2 } (asynchrone Funktion () { für warte (const x von gen2()) { console.log(x); } })(); // Ausgabe: // A // B Wenn in einem asynchronen Generator eine Ausnahme ausgelöst wird, wird die Ausnahme auch in ein Promise verpackt: asynchrone Funktion* asyncGenerator() { neuen Fehler werfen('Problem!'); } asyncGenerator().weiter() .catch(err => console.log(err)); // Fehler: Problem! Asynchrone Methoden und asynchrone GeneratorenEine asynchrone Methode ist eine mit einer asynchronen Funktion deklarierte Methode, die ein Promise-Objekt zurückgibt. Die Rückgabe oder die ausgelöste Ausnahme in der Funktion wird als Wert im zurückgegebenen Promise verwendet. (asynchrone Funktion () { gib "Hallo" zurück; })() .then(x => console.log(x)); // hallo (asynchrone Funktion () { neuen Fehler werfen('Problem!'); })() .catch(x => console.error(x)); // Fehler: Problem! Asynchrone Generatoren sind Methoden, die mit der asynchronen Funktion * deklariert werden. Es gibt ein asynchrones Iterable zurück. Durch den Aufruf der nächsten Methode von Iterable wird ein Promise zurückgegeben. Der vom asynchronen Generator gelieferte Wert wird verwendet, um den Wert des Promise auszufüllen. Wenn im Generator eine Ausnahme ausgelöst wird, wird sie auch von Promise abgefangen. asynchrone Funktion* gen() { ergebe "Hallo"; } const genObj = gen(); genObj.next().then(x => console.log(x)); // { Wert: 'Hallo', fertig: false } Oben finden Sie eine ausführliche Erläuterung der neuen Funktion von ES9, der asynchronen Iteration. Weitere Informationen zur neuen Funktion von ES9, der asynchronen Iteration, finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: MySQL max_allowed_packet-Einstellung
>>: So gehen Sie mit verstümmelten Zeichen in der MySQL-Datenbank um
Inhaltsverzeichnis Klassenkomponente Funktionale ...
Zuvor hatte ich WordPress selbst erstellt, aber d...
Einführung in Dockerfile Docker kann automatisch ...
Vorwort MySQL unterstützt viele Arten von Tabelle...
Inhaltsverzeichnis 1. Partikeleffekte 2. Laden Si...
Virtuelle Hosts verwenden spezielle Software- und...
Einigen Eigenschaften in CSS geht ein "*&quo...
html <!DOCTYPE html> <html lang="de...
W3Cschool erklärt es so Das <meta>-Element l...
Klicken Sie auf die Schaltfläche, um den Text in ...
Öffnen Sie den Editor für geplante Aufgaben. Cent...
Inhaltsverzeichnis 1. Beschreibung 2. Laden Sie d...
Inhaltsverzeichnis Überblick 1. Einfaches Beispie...
beschreiben: Wenn die Tabs-Komponente hin- und he...
Einfache Anwendungsbereitstellung 1. Verzeichniss...