Generator-Funktionen in JavaScript

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.

YouTube Video