Lazy-Funktionen von JavaScript

Hallo!


Ich dachte hier, um Ihnen zu erzählen, wie Sie in JavaScript mithilfe der Fluture-Bibliothek Lazy-Funktionen erstellen und verwenden können. Dies ist eine kurze Übersicht über das Erstellen von Funktionen, den Umgang mit Fehlern und ein wenig über die Parallelität. Funktionale Programmierköpfe werde ich nicht aufsteigen! Ich verspreche es!


Fluture


Fluture ist eine vom Entwickler Aldwin Vlasblom entwickelte Bibliothek, die Future implementiert. Future ist eine Alternative zu Promise, das über eine viel leistungsfähigere API verfügt, die die Implementierung von Abbruch, sicherer "Rekursion", "fehlerfreier" Ausführung (mit beiden) und einem kleinen Wagen mit coolen Funktionen ermöglicht.


Ich denke, es lohnt sich, Ihnen die Methoden (Monaden) zu erläutern, die ich in den folgenden Beispielen verwenden werde.


  • .of(Any) - erstellt aus dem übergebenen Wert eine Zukunft
  • .map(Function) - nein, dies ist nicht Array.map , dies ist eine Transformationsfunktion ähnlich wie Promise.then
  • .chainRej(Function) - wie Promise.catch einen Fehler Promise.catch
  • .fork(Function, Function) - .fork(Function, Function) die zukünftige Ausführung

Erstellen einer Lazy-Funktion


Für mich selbst habe ich zwei Hauptansätze zur Erstellung fauler Funktionen in Fluture hervorgehoben. Der erste Ansatz besteht darin, eine Funktion zu erstellen, die die Quelldaten akzeptiert und eine zur Ausführung bereitstehende Zukunft zurückgibt. Der zweite Ansatz besteht darin, dass wir mit allen beschriebenen Transformationen eine Zukunft erstellen und die Daten dann an sie weitergeben.


Unverständlich? Nehmen wir ein Beispiel! Wir haben eine solche Funktion


 const multiply10 = x => x * 10; 

Jetzt mach sie faul mit dem ersten Ansatz


 const multiply10 = x => x * 10; const lazyMultiply10 = (x) => Future .of(x) //  Future   .map(multiply10); //     lazyMultiply10(2).fork(console.error, console.log); // -> 20 

Zu sperrig, nicht wahr? Versuchen wir, mit dem zweiten Ansatz präziser zu schreiben.


 const multiply10 = x => x * 10; const lazyMultiply10 = Future.map(multiply10); const value = Future.of(2); //     Future lazyMultiply10(value).fork(console.error, console.log); // -> 20 

Schon besser, aber immer noch umständlich. Es muss kompakter sein!


 const lazyMultiply10 = Future.map(x => x * 10); lazyMultiply10(Future.of(2)).fork(console.error, console.log); // -> 20 

Tatsächlich schließen sich diese Ansätze nicht gegenseitig aus und können zusammen verwendet werden.


 const lazyMultiply10 = Future.map(x => x * 10); const someCalculation = a => Future .of(a) .map(v => v + 1) .chain(v => lazyMultiply10(Future.of(v)); someCalculation(10).fork(console.error, console.log); // -> 110 

Fehlerbehandlung


Die Fehlerbehandlung in der Zukunft unterscheidet sich praktisch nicht von der Fehlerbehandlung in Promise. Lass uns erinnere dich Stellen Sie sich eine Funktion vor, die eine Anforderung an eine nicht sehr stabile API eines Drittanbieters sendet.


 const requestToUnstableAPI = query => request({ method: 'get', uri: `http://unstable-site.com/?${query}` }) .then(res => res.data.value) .catch(errorHandler); 

Gleiche Funktion, aber in Zukunft verpackt


 const lazyRequestToUnstableAPI = query => Future .tryP(() => request({ method: 'get', uri: `http://unstable-site.com/?${query}` })) .map(v => v.data.value) .chainRej(err => Future.of(errorHandler(err)); 

Tatsächlich kann die Fehlerbehandlung flexibler gestaltet werden. Dazu benötigen wir die Entweder-Struktur, und diese Kleinheit geht über den Rahmen meiner Überprüfung hinaus.


Parallelität


Um mit Parallelität zu arbeiten, implementiert Future zwei Methoden race(Futures[]) (ähnlich wie Promise.race ), parallel(n, Futures[]) und both(Future, Future) , aber es ist ein Sonderfall von parallel .


Die parallel Methode verwendet zwei Argumente, die Anzahl der parallelen Future und das Array mit Future. Um das parallel Verhalten mit der Promise.all Methode Promise.all , müssen Sie die Anzahl der Promise.all festlegen, die als Infinity .


Auch hier können wir nicht auf Beispiele verzichten.


 const requestF = o => Future.tryP(() => request(o)); const parallel1 = Future.parallel(1); const lazyReqs = parallel1( [ 'http://site.com', 'http://another-site.com', 'http://one-more-site.com', ] .map(requestF) ); lazyReqs.fork(console.error, console.log); // -> [Result1, Result2, Result3] 

Versprechen kompatibel


In JavaScript gibt es keinen Platz für Versprechen, und es ist unwahrscheinlich, dass sich jemand darüber freut, wenn Ihre Methode eine dunkle Zukunft zurückgibt. Zu diesem .promise() verfügt Future über eine .promise() -Methode, mit der die Ausführung von Future gestartet und in Promise eingeschlossen wird.


 Future .of(10) .promise(); // -> Promise{value=10} 

Referenzen



Das ist vielleicht alles, was ich dir sagen wollte. Wenn das Thema interessant ist, lassen Sie es mich wissen, ich werde Ihnen mehr über die Fehlerbehandlung erzählen. Und ja, schimpfe nicht viel mit mir, dies ist mein erster Beitrag auf Habré.

Source: https://habr.com/ru/post/de435838/


All Articles