ÜberblickIn der Programmiersprachentheorie ist Lazy Evaluation (englisch: Lazy Evaluation), auch übersetzt als Lazy Calculation, Lazy Evaluation, auch Call-by-Need genannt, ein Konzept der Computerprogrammierung. Sein Zweck besteht darin, den Arbeitsaufwand des Computers zu minimieren. Es hat zwei verwandte, aber unterschiedliche Bedeutungen, die als „verzögerte Auswertung“ und „minimierte Auswertung“ ausgedrückt werden können. Neben Leistungsverbesserungen besteht der wichtigste Vorteil der verzögerten Auswertung darin, dass ein unendlicher Datentyp erstellt werden kann. Nachdem ich die Lazy Evaluation in funktionalen Sprachen gesehen hatte, wollte ich eine möglichst einfache Implementierung in JavaScript schreiben, um mein Verständnis der Lazy Evaluation zu vertiefen. Es werden zwei Methoden verwendet, die beide weniger als 80 Zeilen benötigen, um eine grundlegende Array-Lazy-Auswertung zu implementieren. So erreichen Sie esBei der verzögerten Auswertung wird nicht bei jeder Auswertung ein Wert zurückgegeben, sondern eine Auswertungsfunktion mit Berechnungsparametern. Die Berechnung wird jedes Mal ausgeführt, wenn der Wert verwendet werden soll. Wenn mehrere verzögerte Operationen vorhanden sind, wird eine Kette von Auswertungsfunktionen gebildet. Bei jeder Auswertung wertet jede Auswertungsfunktion die vorherige Auswertungsfunktion aus und gibt einen Wert zurück. Wenn die Berechnungsfunktion schließlich beendet wird, wird ein Beendigungswert zurückgegeben. Konkrete UmsetzungBestimmen Sie die Beendigung der BewertungsfunktionJede Auswertung der Funktion gibt unterschiedliche Daten zurück. Daher muss ein eindeutiger Wert als Markierung verwendet werden, um zu bestimmen, ob der Fluss abgeschlossen ist. Es kommt einfach vor, dass Symbol() ein neues Symbol erstellen kann, dessen Wert keinem anderen Wert entspricht. const over = Symbol(); const istÜber = Funktion (_Über) { Rückgabewert _over === über; } Funktionsbereich generierenDie Bereichsfunktion akzeptiert einen Start- und einen Endparameter, gibt eine Auswertungsfunktion zurück, führt die Auswertungsfunktion aus, um einen Wert zurückzugeben, und gibt den Endwert zurück, wenn sie beendet wird. const range = Funktion (von, bis) { sei i = von; Rückgabefunktion () { wenn (i < bis) { ich++ console.log('Bereich\t', i); Rückkehr ich } zurückkommen; } } TransformationsfunktionskarteAkzeptiert eine Auswertungsfunktion und eine Verarbeitungsfunktion, ruft die Daten im Auswertungsfunktionsfluss ab, verarbeitet die Daten und gibt einen Fluss zurück. const map = Funktion (Flow, Transform) { Rückgabefunktion () { const Daten = Fluss(); console.log('map\t', Daten); gibt isOver(Daten) zurück? Daten: transformieren(Daten); } } FilterAkzeptiert eine Auswertungsfunktion, filtert die Daten im Auswertungsfunktionsfluss, findet die passenden Daten und gibt sie zurück. const filter = Funktion (Fluss, Bedingung) { Rückgabefunktion () { während(wahr) { const Daten = Fluss(); wenn (isOver(data)) { Daten zurückgeben; } wenn(Bedingung(Daten)) { console.log('filter\t', Daten); Daten zurückgeben; } } } } Unterbrechungsfunktion stoppenAkzeptiert eine Auswertungsfunktion und unterbricht, wenn eine bestimmte Bedingung erreicht ist. Sie können eine Abschlussfunktion plus eine Stoppfunktion verwenden und dann eine Take-Funktion implementieren. const stop = Funktion (Fluss, Bedingung) { lass _stop = false; Rückgabefunktion () { wenn (_stop) zurückgeben; const Daten = Fluss(); wenn (isOver(data)) { Daten zurückgeben; } _stop = Bedingung(Daten); Daten zurückgeben; } } const take = Funktion(Fluss, Num) { sei i = 0; Rückgabestopp (Flow, (Daten) => { gibt ++i >= num zurück; }); } Sammlungsfunktion JoinDa alles, was zurückgegeben wird, eine Funktion ist, müssen wir am Ende eine Join-Funktion verwenden, um alle Werte zu sammeln und ein Array zurückzugeben. const join = Funktion (Fluss) { konstantes Array = []; während(wahr) { const Daten = Fluss(); wenn (isOver(data)) { brechen; } array.push(Daten); } Array zurückgeben; } prüfen:const nums = join(take(filter(map(range(0, 20), n => n * 10), n => n % 3 === 0), 2)); console.log(Zahlen); Ausgabe:
Eine elegantere ImplementierungDie verzögerte Auswertung wird mit den oben genannten Funktionen + Abschlüssen implementiert, ist aber immer noch nicht elegant genug. Der Großteil des Codes wird iteriert und beurteilt, ob die Auswertung abgeschlossen ist. Tatsächlich gibt es eine bessere Möglichkeit, in es6 eine verzögerte Auswertung zu erreichen, nämlich die Verwendung von Generatoren. Generatoren haben uns geholfen, Iterationen zu lösen und festzustellen, ob der Fluss abgeschlossen ist. Wir können uns auf die Logik konzentrieren und prägnanteren, leicht verständlichen und klar strukturierten Code schreiben. const range = Funktion* (von, bis) { für(lass i = von; i < bis; i++) { console.log('Bereich\t', i); Ertrag i; } } const map = Funktion*(Fluss, Transformation) { für (const data of flow) { console.log('map\t', Daten); Ertrag(Transformation(Daten)); } } const filter = funktion*(fluss, bedingung) { für (const data of flow) { console.log('filter\t', Daten); wenn (Bedingung(Daten)) { Ertragsdaten; } } } const stop = Funktion*(Fluss, Bedingung) { für (const data of flow) { Ertragsdaten; wenn (Bedingung(Daten)) { brechen; } } } const take = Funktion (Fluss, Zahl) { lass count = 0; const _filter = Funktion (Daten) { zählen++ gibt Anzahl >= Zahl zurück; } Rückgabestopp (Flow, _Filter); } Vervollständigt wird es durch das Hinzufügen von Kettenaufrufen. Klasse _Lazy{ Konstruktor() { dieser.iterator = null; } Bereich(...args) { dieser.Iterator = Bereich(...args); gib dies zurück; } Karte(...args) { dieser.iterator = map(dieser.iterator, ...args); gib dies zurück; } filter(...args) { dieser.Iterator = Filter(dieser.Iterator, ...Argumente); gib dies zurück; } nehme(...args) { dieser.iterator = nehme(diesen.iterator, ...args); gib dies zurück; } [Symbol.iterator]() { gib diesen Iterator zurück; } } Funktion faul () { gibt neues _Lazy() zurück; } Zum Schluss testen Sie es noch einmal: const nums = lazy().range(0, 100).map(n => n * 10).filter(n => n % 3 === 0).take(2); für (sei n von Nums) { console.log('num:\t', n, '\n'); } Ausgabe:
Okay, es ist erledigt. ZusammenfassenAuf diese Weise haben wir eine einfache Bibliothek für die verzögerte Array-Auswertung fertiggestellt. Hier implementieren wir lediglich die verzögerte Auswertung. Um sie in das Projekt einzufügen, müssen viele Details hinzugefügt werden. Da der Code nur 80 Zeilen umfasst, können Sie das Prinzip der Lazy Evaluation klar verstehen und Ihr Verständnis von Generatoren vertiefen. Oben finden Sie Einzelheiten zur Implementierung einer Array-Lazy-Evaluation-Bibliothek mit JavaScript. Weitere Informationen zur Implementierung einer Array-Lazy-Evaluation-Bibliothek mit JavaScript finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: MySQL-Tutorial zum Bereitstellen mehrerer Instanzen auf einer einzigen Maschine mit mysqld_multi
>>: So erstellen Sie eine lnmp-Umgebung im Docker
Für viele HTML-Neulinge ist die Tabelle <table...
1. JDK installieren Überprüfen Sie die Betriebsda...
Online-Vorschau https://jsrun.pro/AafKp/ Erster B...
Grundlegende Netzwerkkonfiguration Obwohl Docker ...
Das Umschreibmodul ist das Modul ngx_http_rewrite...
Hintergrund Vor nicht allzu langer Zeit habe ich ...
Finden Sie das Problem Schauen wir uns zunächst d...
Um die folgenden beiden Dateien zusammenzuführen,...
Bereiten Sie die Zutaten wie oben gezeigt vor (ps...
In diesem Artikel werden Ihnen zwei Methoden zum ...
Vorwort <br />Ich arbeite schon eine ganze W...
Ich habe vor Kurzem die 34 goldenen Regeln von Yah...
In diesem Artikel wird beschrieben, wie Sie das P...
Inhaltsverzeichnis 1. Laden Sie die Systemabbildd...
Inhaltsverzeichnis 1. Der Grund, warum das Limit ...