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
Da myeclipse2017 und idea2017 auf dem Computer in...
Manchmal erfordert die lokale Entwicklung das Deb...
Neun einfache Beispiele analysieren die Verwendun...
Um eine Tabelle in HTML zu zeichnen, verwenden Si...
Ich bin ein SQL-Anfänger und dachte, die Installa...
1. MIME: Mehrzweck-Internet-Mail-Erweiterungen Da...
Da meine Entwicklungsumgebung darin besteht, Cent...
1. Verwenden Sie zunächst Springboot, um ein einf...
Detaillierte Erklärung zum MySQL-Export von Daten...
Tutorial zur Netzwerknutzung Offizielle Website d...
Deinstallieren von MySQL 1. Deinstallieren Sie in...
Das Ziel von Google mit Flutter bestand immer dar...
Verwendung von v-on:clock in Vue Ich lerne derzei...
Inhaltsverzeichnis 1.mysqldump Ausführungsprozess...
Es gibt einen großen Unterschied zwischen der Sch...