Wie unterstützt die Promise.coroutine den Generator als nachgebenden Wert?

7

Promise.coroutine unterstützt Promise als nachgebenden Werttyp. Und über die addYieldHandler(function handler) kann Promise.coroutine auch alle Typen unterstützen, die nur einmal resultieren. Aber wie könnte ich einen yieldHandler schreiben, der einen generator -Typ wie co verarbeiten kann?

    
user552403 30.09.2014, 02:17
quelle

1 Antwort

26

Erstens, Bluebird Coroutines geben Versprechen zurück, die natürlich auf eigene Faust möglich sind:

%Vor%

Im Allgemeinen ist ein Generator syntaktischer Zucker für eine Funktion, die eine iterierbare Sequenz zurückgibt. In der Natur gibt es nichts Asynchrones. Sie können Code schreiben, der iterables in ES5 und sogar ES3 zurückgibt, und ihn mit yield in einem Generator verbrauchen.

Nun - wie für Ihre Frage:

Ich würde nicht empfehlen, Promise.coroutine so zu verwenden.

Die Ausgabe von beliebigen Iterablen aus dem spezifischen Iterable, das Sie verwenden, ist fehleranfällig. Wenn Sie es in Promise.coroutine umbrechen, wird es zu einer expliziten Coroutine, die Sie leicht ausgeben können. Dies ist explizit, klar und bewahrt alle möglichen nützlichen Eigenschaften.

Das Ausgeben von Versprechen ist kein Zufall, und es gibt einen guten Grund, dass async Funktionen in ES7 auf Versprechungen warten. Versprechen stellen einen zeitlichen Wert dar und sie sind wirklich das einzige Ding, auf das man warten muss, das macht Sinn - sie repräsentieren genau das - etwas, auf das man wartet. Aus diesem Grund ist das explizite Warten auf Versprechungen vorteilhaft und sorgt für eine solide Abstraktion.

Wenn Sie von einem beliebigen Generator profitieren wollen, müssen Sie keinen Ertrags-Handler über Bluebird hinzufügen.

Generatoren in JavaScript haben diese Fähigkeit bereits mit einer speziellen Notation eingebaut. Es ist nicht nötig, eine spezielle Ausnahme für eine bestimmte Versprechens-Bibliothek hinzuzufügen, um aus anderen Iterablen zu ergeben.

%Vor%

Das Ausgeben aus einer anderen Sequenz ist bereits in Generatoren eingebaut. Wenn Sie von einem anderen Generator liefern wollen, können Sie einfach yield * aufrufen. Auf diese Weise ist es explizit, dass Sie delegieren. Es ist nur ein weiteres Zeichen des Codes, aber es ist viel expliziter und es ist auch einfacher, mit Debuggern durchzukommen, da die Engine die Delegierung kennt. Ich ziehe es immer noch vor, nur Versprechungen zu machen, aber wenn Sie sich darüber stark fühlen, klingt das Delegieren zu anderen Generatoren viel besser, als Generatoren explizit abzugeben.

Beachten Sie, dass dies auch viel schneller ist, als explizite Generierung von Generatoren, da der Konvertierungsprozess von Promise.coroutine nicht billig ist, da er einmal ausgeführt und dann verwendet werden soll, so dass die Konvertierung nicht schnell ist, aber sehr schnell ist Funktion (schneller als async in fast allen Anwendungsfällen und schneller als die meisten Leute schreiben Callacks in den meisten Anwendungsfällen. Wenn Sie delegieren, anstatt jedes Mal eine Coroutine zu erstellen und auszuführen - Sie haben eine bessere Leistung.

>

Wenn Sie darauf bestehen, können Sie addYieldHandler

Es ist durchaus möglich, dies zu tun. Wenn Sie mit der Geschwindigkeitsstrafe und der (meiner Meinung nach schlechteren) Abstraktion einverstanden sind. Sie können addYieldHandler verwenden, um Generatoren zu erzeugen.

Zuerst der "gute" Weg:

%Vor%

Hier - wir haben die Fähigkeit hinzugefügt, iterables und nicht Generatoren zu liefern, der Vorteil ist, dass Funktionen, die keine Generatoren sind (zum Beispiel - aus Bibliotheken von Drittanbietern), aber immer noch iterierbare ergeben können. Die Verwendung des obigen ist etwas in der Art von: yield generatorFn() , wo Sie den Generator aufrufen. Beachten Sie, dass unser Code hier repliziert, was Promise.coroutine tatsächlich tut, und wir hatten fast eine "native" Implementierung davon.

Wenn Sie jetzt Generatoren erzeugen wollen, können Sie das immer noch tun:

%Vor%

Das ist der Vollständigkeit halber aber:)

    
Benjamin Gruenbaum 30.09.2014 06:56
quelle