Generator-Funktionen in JavaScript
In diesem Artikel werden wir Generator-Funktionen in JavaScript erklären.
YouTube Video
Generator-Funktionen in JavaScript
JavaScript-Generator-Funktionen sind spezielle Funktionen, die sich von regulären Funktionen dadurch unterscheiden, dass sie Lazy Execution durchführen und pausieren und wieder aufnehmen können. Mit dem Verständnis von Generator-Funktionen können Sie asynchrone Operationen und die sequentielle Verarbeitung großer Datenmengen effizient handhaben. Hier bieten wir eine detaillierte Erklärung, wie Generator-Funktionen funktionieren, wie man sie verwendet und praktische Anwendungsfälle.
Was sind Generator-Funktionen?
Eine Generator-Funktion wird mit function*
(einer Funktionsdefinition mit einem Sternchen) definiert und kann, anders als reguläre Funktionen, die Ausführung anhalten und an einem späteren Punkt mit beibehaltetem Zustand fortsetzen. Generator-Funktionen ermöglichen "Lazy Execution" und geben Ergebnisse schrittweise zurück, was effizientes Speichermanagement und sequentielle Verarbeitung ermöglicht.
Syntax
1function* generatorFunction() {
2 yield 'First value';
3 yield 'Second value';
4 return 'Done';
5}
Auf diese Weise kann eine Generator-Funktion mehrere yield
-Ausdrücke enthalten und die Ausführung mithilfe von yield
pausieren. Wenn eine Generator-Funktion aufgerufen wird, wird der Funktionskörper nicht sofort ausgeführt, sondern es wird ein Generator-Objekt zurückgegeben. Sie können die next()
-Methode auf diesem Objekt aufrufen, um die Funktion von der Stelle aus fortzusetzen, an der sie pausiert wurde.
Grundlegende Verwendung von Generator-Funktionen
Schauen wir uns als Nächstes ein grundlegendes Beispiel für die Verwendung von Generator-Funktionen an.
1function* simpleGenerator() {
2 yield 1;
3 yield 2;
4 yield 3;
5}
6
7const gen = simpleGenerator();
8
9console.log(gen.next()); // { value: 1, done: false }
10console.log(gen.next()); // { value: 2, done: false }
11console.log(gen.next()); // { value: 3, done: false }
12console.log(gen.next()); // { value: undefined, done: true }
Ein wichtiger Punkt ist, dass der Generator jedes Mal Werte mit yield
zurückgibt und solange die Eigenschaft done
auf false
steht, bedeutet das, dass weitere Werte folgen. Der letzte Aufruf von next()
gibt done: true
zurück, was anzeigt, dass der Generator abgeschlossen ist.
Das yield
-Schlüsselwort und das Pausieren von Werten
yield
ist ein Schlüsselwort, das einen Pausenpunkt innerhalb einer Generator-Funktion anzeigt. Der Wert rechts von yield
wird zurückgegeben, wenn next()
aufgerufen wird. Außerdem ermöglicht yield
eine bidirektionale Kommunikation. Mit anderen Worten, wenn ein Wert als Argument an die next()
-Methode übergeben wird, wird dieser Wert an die Generator-Funktion gesendet.
1function* generatorWithYield() {
2 const value1 = yield 'First yield';
3 console.log('Received value:', value1);
4 const value2 = yield 'Second yield';
5 console.log('Received value:', value2);
6}
7
8const gen = generatorWithYield();
9
10console.log(gen.next()); // { value: 'First yield', done: false }
11console.log(gen.next('Apple')); // Received value: Apple
12 // { value: 'Second yield', done: false }
13console.log(gen.next('Banana'));// Received value: Banana
14 // { value: undefined, done: true }
In diesem Beispiel sendet der Aufruf next('Apple')
den Wert 'Apple'
an die Generator-Funktion, wo er innerhalb der Funktion verwendet wird.
Verwalten des Generator-Zustands
Generatoren können ihren Ausführungszustand beibehalten, was eine prägnante Darstellung langer Schleifen oder eine sequentielle Verarbeitung ermöglicht. Das folgende Beispiel zeigt einen Generator, der unbegrenzt Zahlen erzeugt.
1function* infiniteGenerator() {
2 let i = 0;
3 while (true) {
4 yield i++;
5 if (i > 10) {
6 break;
7 }
8 }
9}
10
11const gen = infiniteGenerator();
12
13console.log(gen.next().value); // 0
14console.log(gen.next().value); // 1
15console.log(gen.next().value); // 2
16// Continues...
Dieser Generator erzeugt kontinuierlich Zahlen mit einer while(true)
-Schleife, sodass Sie bei Bedarf Werte abrufen können. Dies ermöglicht eine effiziente Verarbeitung großer Datenmengen.
Anwendungen von Generator-Funktionen
Generator-Funktionen eignen sich zur sequentiellen Ausführung mehrerer Prozesse. Beispielsweise sind sie nützlich, um API-Anfragen sequenziell zu verarbeiten oder große Dateien zu teilen und zu verarbeiten.
1function* apiRequestGenerator() {
2 yield fetch('https://codesparklab.com/json/example1.json');
3 yield fetch('https://codesparklab.com/json/example2.json');
4 yield fetch('https://codesparklab.com/json/example3.json');
5}
Daher sind Generatoren, die für asynchrones Verarbeiten verwendet werden können, äußerst vorteilhaft für eine effiziente sequenzielle Datenverarbeitung.
Asynchrone Generatoren
Asynchrone Generatoren, die in ES2018 eingeführt wurden, ermöglichen es, asynchrone Werte sequenziell durch die Kombination von async
und yield
zurückzugeben. Dies ermöglicht es, asynchrone Verarbeitung in Kombination mit await
prägnant zu schreiben.
Syntax
1async function* asyncGenerator() {
2 yield await Promise.resolve(1);
3 yield await Promise.resolve(2);
4 yield await Promise.resolve(3);
5}
6
7const gen = asyncGenerator();
8
9(async () => {
10 for await (const value of gen) {
11 console.log(value); // 1, 2, 3
12 }
13})();
Asynchrone Generatoren können Werte sequenziell mit einer for await...of
-Schleife abrufen. Dieses Muster ist besonders nützlich bei der Verarbeitung asynchroner Datenströme.
Praktisches Beispiel: Vereinfachung der asynchronen Verarbeitung mit Generatoren
Generator-Funktionen werden auch verwendet, um den Ablauf der asynchronen Verarbeitung zu vereinfachen. Zum Beispiel können Sie durch die Kombination von yield
und Promise
, wie unten gezeigt, asynchrone Operationen schreiben, die wie synchrone aussehen.
1function* asyncFlow() {
2 const data1 = yield fetch('https://codesparklab.com/json/example1.json');
3 console.log(data1);
4 const data2 = yield fetch('https://codesparklab.com/json/example2.json');
5 console.log(data2);
6}
7
8const gen = asyncFlow();
9
10function handleAsync(generator) {
11 const next = (promise) => {
12 promise.then((result) => {
13 const { value, done } = generator.next(result);
14 if (!done) {
15 next(value);
16 }
17 });
18 };
19
20 next(generator.next().value);
21}
22
23handleAsync(gen);
Dieser Code führt API-Anfragen sequenziell mithilfe eines Generators aus und verarbeitet die Ergebnisse.
Zusammenfassung
Generator-Funktionen sind eine der leistungsstarken Funktionen von JavaScript, da sie die Ausführung einer Funktion anhalten und fortsetzen können. Dies ermöglicht eine sequenzielle Verarbeitung, asynchrone Verarbeitung und eine effiziente Handhabung großer Datenmengen. Das Verständnis von Generatoren ist ein wichtiger Schritt, um fortgeschrittene Techniken in JavaScript zu beherrschen.
Sie können den obigen Artikel mit Visual Studio Code auf unserem YouTube-Kanal verfolgen. Bitte schauen Sie sich auch den YouTube-Kanal an.