Heim >Web-Frontend >js-Tutorial >JavaScript-Generatoren: Laden Sie Ihren Code mit Pausenleistung auf!
JavaScript-Generatoren sind ziemlich cool. Sie ähneln regulären Funktionen, verfügen jedoch über Superkräfte. Ich habe sie in letzter Zeit häufig verwendet und ich muss sagen, sie haben die Art und Weise verändert, wie ich über den Kontrollfluss in meinem Code denke.
Beginnen wir mit den Grundlagen. Ein Generator ist eine Funktion, die angehalten und fortgesetzt werden kann. Es verwendet die Function*-Syntax und das Schlüsselwort yield. Hier ist ein einfaches Beispiel:
function* countToThree() { yield 1; yield 2; yield 3; } const counter = countToThree(); console.log(counter.next().value); // 1 console.log(counter.next().value); // 2 console.log(counter.next().value); // 3
Sehen Sie, wie wir die Funktion Ertrag für Ertrag durchlaufen können? Das ist die Magie von Generatoren.
Aber Generatoren können noch viel mehr als nur zählen. Sie eignen sich hervorragend zum Erstellen benutzerdefinierter Iteratoren. Angenommen, Sie möchten eine Fibonacci-Folge generieren:
function* fibonacci() { let [prev, curr] = [0, 1]; while (true) { yield curr; [prev, curr] = [curr, prev + curr]; } } const fib = fibonacci(); for (let i = 0; i < 10; i++) { console.log(fib.next().value); }
Dieser Generator wird für immer Fibonacci-Zahlen erzeugen. Es ist eine unendliche Folge, aber wir berechnen nur die Werte, die wir brauchen.
Das bringt uns zu einem der coolsten Dinge an Generatoren: Lazy Evaluation. Sie berechnen Werte nur, wenn wir danach fragen. Dies kann bei großen Datensätzen oder komplexen Berechnungen sehr effizient sein.
Sehen wir uns ein praktischeres Beispiel an. Angenommen, Sie erstellen ein Paginierungssystem für einen großen Datensatz:
function* paginate(items, pageSize) { for (let i = 0; i < items.length; i += pageSize) { yield items.slice(i, i + pageSize); } } const allItems = Array.from({ length: 100 }, (_, i) => i + 1); const pageSize = 10; const pages = paginate(allItems, pageSize); console.log(pages.next().value); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] console.log(pages.next().value); // [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Mit diesem Generator können wir Datenseiten nach Bedarf abrufen, ohne alles auf einmal in den Speicher laden zu müssen.
Generatoren glänzen auch, wenn es um asynchrone Programmierung geht. Sie können dafür sorgen, dass asynchroner Code eher wie synchroner Code aussieht und sich so verhält. Hier ist ein Beispiel für die Verwendung der Co-Bibliothek:
const co = require('co'); function* fetchUserData() { const user = yield fetchUser(); const posts = yield fetchPosts(user.id); const comments = yield fetchComments(posts[0].id); return { user, posts, comments }; } co(fetchUserData).then(result => { console.log(result); }).catch(error => { console.error(error); });
Dieser Code sieht synchron aus, führt jedoch tatsächlich drei asynchrone Aufrufe durch. Der Generator pausiert bei jedem Ertrag, bis das Versprechen erfüllt ist.
Generatoren können auch für kooperatives Multitasking verwendet werden. Sie können mehrere Generatoren erstellen und zwischen ihnen wechseln und so die gleichzeitige Ausführung simulieren:
function* task1() { yield 'Start task 1'; yield 'Middle of task 1'; yield 'End task 1'; } function* task2() { yield 'Start task 2'; yield 'Middle of task 2'; yield 'End task 2'; } function run(tasks) { const iterations = tasks.map(task => task()); while (iterations.length) { const [first, ...rest] = iterations; const { value, done } = first.next(); if (!done) { console.log(value); iterations.push(first); } iterations.unshift(...rest); } } run([task1, task2]);
Dieser Code wechselt zwischen den beiden Aufgaben und führt jeweils einen Schritt nach dem anderen aus.
Generatoren eignen sich auch hervorragend zum Erstellen von Zustandsmaschinen. Jeder Ertrag kann einen anderen Zustand darstellen:
function* trafficLight() { while (true) { yield 'red'; yield 'green'; yield 'yellow'; } } const light = trafficLight(); console.log(light.next().value); // red console.log(light.next().value); // green console.log(light.next().value); // yellow console.log(light.next().value); // red
Diese Ampel wird auf unbestimmte Zeit durch ihre Zustände radeln.
Lassen Sie uns nun über einige fortgeschrittenere Techniken sprechen. Durch die Generatordelegation können Sie einem anderen Generator nachgeben:
function* innerGenerator() { yield 'inner 1'; yield 'inner 2'; } function* outerGenerator() { yield 'outer 1'; yield* innerGenerator(); yield 'outer 2'; } const gen = outerGenerator(); console.log(gen.next().value); // outer 1 console.log(gen.next().value); // inner 1 console.log(gen.next().value); // inner 2 console.log(gen.next().value); // outer 2
Die yield*-Syntax wird an innerGenerator delegiert und gibt alle seine Werte aus, bevor mit äußeremGenerator fortgefahren wird.
Erwähnenswert ist auch die Fehlerbehandlung in Generatoren. Mit der throw()-Methode können Sie Fehler in einen Generator werfen:
function* errorGenerator() { try { yield 'Start'; yield 'Middle'; yield 'End'; } catch (error) { console.error('Caught:', error); yield 'Error handled'; } } const gen = errorGenerator(); console.log(gen.next().value); // Start console.log(gen.throw(new Error('Oops!')).value); // Caught: Error: Oops! // Error handled
Dies ermöglicht einige ziemlich ausgefeilte Fehlerbehandlungsstrategien.
Generatoren können auch zur Implementierung von Backtracking-Algorithmen verwendet werden. Hier ist ein einfaches Beispiel, das alle möglichen Kombinationen von Elementen generiert:
function* countToThree() { yield 1; yield 2; yield 3; } const counter = countToThree(); console.log(counter.next().value); // 1 console.log(counter.next().value); // 2 console.log(counter.next().value); // 3
Dieser Generator erzeugt alle 2-Element-Kombinationen der angegebenen Elemente.
Ein Bereich, in dem Generatoren wirklich glänzen, ist die Verarbeitung großer Datenmengen. Sie können effiziente Datenverarbeitungspipelines erstellen, die nur das berechnen, was benötigt wird. Hier ist ein Beispiel, das eine große Datei Zeile für Zeile verarbeitet:
function* fibonacci() { let [prev, curr] = [0, 1]; while (true) { yield curr; [prev, curr] = [curr, prev + curr]; } } const fib = fibonacci(); for (let i = 0; i < 10; i++) { console.log(fib.next().value); }
Dieser Generator liest die Datei Zeile für Zeile, sodass Sie große Dateien verarbeiten können, ohne sie vollständig in den Speicher zu laden.
Generatoren können auch zur Implementierung des Observable-Musters verwendet werden. Hier ist eine einfache Implementierung:
function* paginate(items, pageSize) { for (let i = 0; i < items.length; i += pageSize) { yield items.slice(i, i + pageSize); } } const allItems = Array.from({ length: 100 }, (_, i) => i + 1); const pageSize = 10; const pages = paginate(allItems, pageSize); console.log(pages.next().value); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] console.log(pages.next().value); // [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Dieser Generator fungiert als Beobachter und verarbeitet jedes Datenelement, das er empfängt.
Eine weitere coole Verwendung von Generatoren ist die Erstellung benutzerdefinierter Kontrollstrukturen. Hier ist ein Beispiel für eine Wiederholungsfunktion, die Generatoren verwendet:
const co = require('co'); function* fetchUserData() { const user = yield fetchUser(); const posts = yield fetchPosts(user.id); const comments = yield fetchComments(posts[0].id); return { user, posts, comments }; } co(fetchUserData).then(result => { console.log(result); }).catch(error => { console.error(error); });
Diese Wiederholungsfunktion wird die angegebene Funktion bis zu max. Versuche lang versuchen, bevor sie aufgibt.
Zusammenfassend lässt sich sagen, dass Generatoren eine leistungsstarke Funktion von JavaScript sind, die Ihnen dabei helfen kann, aussagekräftigeren, effizienteren und wartbareren Code zu schreiben. Sie eignen sich hervorragend für die Handhabung komplexer Kontrollflüsse, die Verwaltung asynchroner Vorgänge und die Verarbeitung großer Datensätze. Auch wenn sie auf den ersten Blick vielleicht etwas seltsam erscheinen, werden Sie, sobald Sie den Dreh raus haben, alle möglichen kreativen Möglichkeiten finden, sie in Ihren Projekten zu verwenden. Probieren Sie Generatoren also in Ihrem nächsten JavaScript-Projekt aus. Sie werden überrascht sein, wie sehr sie Ihren Code vereinfachen können!
Schauen Sie sich unbedingt unsere Kreationen an:
Investor Central | Intelligentes Leben | Epochen & Echos | Rätselhafte Geheimnisse | Hindutva | Elite-Entwickler | JS-Schulen
Tech Koala Insights | Epochs & Echoes World | Investor Central Medium | Puzzling Mysteries Medium | Wissenschaft & Epochen Medium | Modernes Hindutva
Das obige ist der detaillierte Inhalt vonJavaScript-Generatoren: Laden Sie Ihren Code mit Pausenleistung auf!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!