Ich habe von einem "Yield" -Schlüsselwort in JavaScript gehört, aber ich habe eine sehr schlechte Dokumentation darüber gefunden. Kann mir jemand erklären (oder eine Website empfehlen, die erklärt), wie sie verwendet wird und wofür sie verwendet wird?
javascript
yield
keyword
mck89
quelle
quelle
Antworten:
Die MDN-Dokumentation ist ziemlich gut, IMO.
quelle
Späte Antwort, wahrscheinlich weiß
yield
jetzt jeder Bescheid , aber es ist eine bessere Dokumentation hinzugekommen.Anpassung eines Beispiels aus "Javascript's Future: Generators" von James Long für den offiziellen Harmony-Standard:
So
yield
ist esreturn
: Du bekommst etwas zurück.return x
Gibt den Wert von zurückx
, gibt jedochyield x
eine Funktion zurück, mit der Sie zum nächsten Wert iterieren können. Nützlich, wenn Sie eine möglicherweise speicherintensive Prozedur haben , die Sie möglicherweise während der Iteration unterbrechen möchten.quelle
function* foo(x){
da*
Token hinzuzufügen . Ob Sie es brauchen oder nicht, hängt von der Art der Zukunft ab, in die Sie zurückkehren. Das Detail ist lang: GvR erklärt es für die Python-Implementierung , nach der die Javascript-Implementierung modelliert ist. Die Verwendungfunction *
ist immer richtig, in einigen Fällen jedoch etwas mehr Aufwand alsfunction
beiyield
.function *
undyield
und fügte den angegebenen Fehler hinzu ("Ein früher Fehler wird ausgelöst, wenn in einer Nicht-Generator-Funktion ein Ertrag oder ein Ertrag * -Ausdruck auftritt"). Für die ursprüngliche Implementierung von Javascript 1.7 in Firefox war das jedoch nicht erforderlich*
. Antwort entsprechend aktualisiert. Vielen Dank!Es ist wirklich einfach, so funktioniert es
yield
Stichwort hilft einfach zu pausieren und wieder eine Funktion in jederzeit asynchron .Nehmen Sie diese einfache Generatorfunktion :
Bis Sie das nennen _process.next () es würde nicht die Ausführungs ersten 2 Zeilen von Code, dann ist die erste Ausbeute wird pausiert die Funktion. Um wieder auf die Funktion bis zum nächsten Pause Punkt ( Ausbeute Schlüsselwort ) Sie müssen rufen _process.next () .
Aber während Ausbeute führt diese Pause und Lebenslauf Verhalten kann es einige Ergebnisse zurück als auch
{value: any, done: boolean}
nach der vorherige Funktion wir keine Werte emittieren haben. Wenn wir die vorherige Ausgabe untersuchen, wird dieselbe{ value: undefined, done: false }
mit einem undefinierten Wert angezeigt .Lassen Sie uns in das Yield-Schlüsselwort eintauchen. Optional können Sie einen Ausdruck hinzufügen und einen optionalen Standardwert zuweisen . (Offizielle Dokumentensyntax)
Ausdruck : Wert, der von der Generatorfunktion zurückgegeben werden soll
rv : Gibt den optionalen Wert zurück, der an die next () -Methode des Generators übergeben wurde
Versuchen Sie es jetzt
Verwendungen
Verweise:
quelle
Wenn ich die Antwort von Nick Sotiros vereinfache (was ich großartig finde), ist es meiner Meinung nach am besten zu beschreiben, wie man mit dem Codieren beginnen würde
yield
.Meiner Meinung nach besteht der größte Vorteil der Verwendung
yield
darin, dass alle verschachtelten Rückrufprobleme, die wir im Code sehen, beseitigt werden. Es ist schwer zu sehen, wie es zuerst geht, weshalb ich beschlossen habe, diese Antwort zu schreiben (für mich selbst und hoffentlich für andere!)Die Art und Weise, wie dies geschieht, besteht darin, die Idee einer Co-Routine einzuführen, die eine Funktion ist, die freiwillig anhalten / pausieren kann, bis sie das bekommt, was sie benötigt. In Javascript wird dies mit bezeichnet
function*
. Nurfunction*
Funktionen können verwendenyield
.Hier ist ein typisches Javascript:
Dies ist umständlich, da sich jetzt Ihr gesamter Code (der offensichtlich auf diesen
loadFromDB
Anruf warten muss) in diesem hässlich aussehenden Rückruf befinden muss. Das ist aus ein paar Gründen schlecht ...})
das Sie überall im Auge behalten müssenfunction (err, result)
Jargonresult
Auf der anderen Seite kann
yield
all dies mit Hilfe des netten Co-Routine-Frameworks in einer Zeile erledigt werden.Und so wird Ihre Hauptfunktion jetzt bei Bedarf nachgeben, wenn sie auf das Laden von Variablen und Dingen warten muss. Um dies auszuführen, müssen Sie jetzt eine normale (Nicht-Coroutine-Funktion) aufrufen . Ein einfaches Co-Routine-Framework kann dieses Problem beheben, sodass Sie nur Folgendes ausführen müssen:
Und der Start ist definiert (aus der Antwort von Nick Sotiro)
Und jetzt können Sie schönen Code haben, der viel besser lesbar, leicht zu löschen und ohne Einrückungen, Funktionen usw. herumspielen muss.
Eine interessante Beobachtung ist, dass es sich in diesem Beispiel
yield
eigentlich nur um ein Schlüsselwort handelt, das Sie einer Funktion mit einem Rückruf vorlegen können.Würde "Hallo Welt" drucken. Sie können also jede Rückruffunktion tatsächlich verwenden,
yield
indem Sie einfach dieselbe Funktionssignatur (ohne cb) erstellen undfunction (cb) {}
wie folgt zurückkehren :Hoffentlich können Sie mit diesem Wissen saubereren, besser lesbaren Code schreiben, der leicht zu löschen ist !
quelle
function*
ist nur eine reguläre Funktion ohne Ausbeute?function *
ist eine Funktion, die Ertrag enthält . Es ist eine spezielle Funktion, die als Generator bezeichnet wird.yield
überall verwenden, ist dies sicher sinnvoller als die Rückrufe, aber ich sehe nicht, wie dies besser lesbar ist als Rückrufe.Um eine vollständige Antwort zu geben:
yield
funktioniert ähnlichreturn
, aber in einem Generator.Für das allgemein gegebene Beispiel funktioniert dies wie folgt:
Es gibt aber auch einen zweiten Zweck des Yield-Schlüsselworts. Es kann verwendet werden, um Werte an den Generator zu senden.
Zur Verdeutlichung ein kleines Beispiel:
Dies funktioniert, wenn der Wert
2
zugewiesen wirdy
, indem er an den Generator gesendet wird, nachdem er bei der ersten Ausbeute (die zurückgegeben wurde0
) gestoppt wurde .Dies ermöglicht es uns, einige wirklich funky Sachen zu machen. (Coroutine nachschlagen)
quelle
Es wird für Iterator-Generatoren verwendet. Grundsätzlich können Sie mit Prozedurcode eine (möglicherweise unendliche) Sequenz erstellen. Siehe Mozillas Dokumentation .
quelle
yield
kann auch verwendet werden, um die Rückrufhölle mit einem Coroutine-Framework zu eliminieren.quelle
Fibonacci-Sequenzgenerator mit dem Schlüsselwort yield.
quelle
Yeild
Schlüsselwort in der JavaScript-Funktion macht es Generator,Was ist Generator in JavaScript?
Das heißt, Generatoren helfen uns, asynchron mit den Hilfe-Iteratoren zu arbeiten. Oh, was sind nun die Hack-Iteratoren? Ja wirklich?
Von wo aus können wir mit dem Iterator einzeln auf das Element zugreifen? Es hilft uns, über Generatorfunktionen auf Elemente zuzugreifen.
Generatorfunktionen sind solche, in denen wir
yeild
Schlüsselwörter verwenden. Yield-Schlüsselwörter helfen uns, die Ausführung der Funktion anzuhalten und wieder aufzunehmenHier ist ein kurzes Beispiel
Lassen Sie mich kurz erklären, was los ist
Sie haben festgestellt, dass die Ausführung bei jedem
yeild
Schlüsselwort angehalten wird und wiryield
mithilfe des Iterators zuerst darauf zugreifen können.next()
Dies iteriert
yield
nacheinander zu allen Schlüsselwörtern und gibt dann undefiniert zurück, wennyield
in einfachen Worten keine Schlüsselwörter mehr vorhanden sind. Sie können sagen, dass dasyield
Schlüsselwort ein Haltepunkt ist, an dem die Funktion jedes Mal pausiert und nur fortgesetzt wird, wenn sie mit dem Iterator aufgerufen wirdFür unseren Fall:
_getMeDrink.next()
Dies ist ein Beispiel für einen Iterator, der uns hilft, auf jeden Haltepunkt in der Funktion zuzugreifenBeispiel für Generatoren:
async/await
Wenn Sie die Implementierung von
async/await
sehen,generator functions & promises
werden Sie sehen, dass sie verwendet werden, umasync/await
Arbeit zu machenBitte weisen Sie darauf hin, dass Vorschläge willkommen sind
quelle
Abhängigkeit zwischen asynchronen Javascript-Aufrufen.
Ein weiteres gutes Beispiel dafür, wie Ausbeute verwendet werden kann.
quelle
Bevor Sie etwas über den Ertrag lernen, müssen Sie sich mit Generatoren auskennen. Generatoren werden mit der
function*
Syntax erstellt. Generatorfunktionen führen keinen Code aus, sondern geben einen Iteratortyp zurück, der als Generator bezeichnet wird. Wenn mit dernext
Methode ein Wert angegeben wird, wird die Generatorfunktion so lange ausgeführt, bis sie auf ein Yield-Schlüsselwort stößt. Mit using erhaltenyield
Sie ein Objekt zurück, das zwei Werte enthält, einer ist value und der andere ist done (boolean). Der Wert kann ein Array, ein Objekt usw. sein.quelle
Ein einfaches Beispiel:
quelle
Ich versuche auch, das Yield-Schlüsselwort zu verstehen. Nach meinem derzeitigen Verständnis funktioniert das Ertragsschlüsselwort im Generator wie ein CPU-Kontextwechsel. Wenn die Yield-Anweisung ausgeführt wird, werden alle Status (z. B. lokale Variablen) gespeichert.
Außerdem wird ein direktes Ergebnisobjekt an den Aufrufer zurückgegeben, z. B. {value: 0, done: false}. Der Aufrufer kann dieses Ergebnisobjekt verwenden, um zu entscheiden, ob der Generator durch Aufrufen von next () erneut aufgeweckt werden soll (durch Aufrufen von next () wird die Ausführung wiederholt).
Ein weiterer wichtiger Punkt ist, dass ein Wert für eine lokale Variable festgelegt werden kann. Dieser Wert kann vom Aufrufer 'next ()' beim 'Aufwecken' des Generators übergeben werden. Beispiel: it.next ('valueToPass') lautet wie folgt: "resultValue = yield slowQuery (1);" Genau wie beim Aufwecken einer nächsten Ausführung kann der Aufrufer ein laufendes Ergebnis in die Ausführung einfügen (in eine lokale Variable einfügen). Für diese Ausführung gibt es also zwei Arten von Zuständen:
der Kontext, der in der letzten Ausführung gespeichert wurde.
Die vom Trigger dieser Ausführung injizierten Werte.
Mit dieser Funktion kann der Generator mehrere asynchrone Vorgänge sortieren. Das Ergebnis der ersten asynchronen Abfrage wird durch Festlegen der lokalen Variablen (resultValue im obigen Beispiel) an die zweite übergeben. Die zweite asynchrone Abfrage kann nur durch die Antwort der ersten asynchronen Abfrage ausgelöst werden. Dann kann die zweite asynchrone Abfrage den Wert der lokalen Variablen überprüfen, um über die nächsten Schritte zu entscheiden, da die lokale Variable ein injizierter Wert aus der Antwort der ersten Abfrage ist.
Die Schwierigkeiten bei asynchronen Abfragen sind:
Rückruf Hölle
Verlust des Kontexts, sofern sie nicht als Parameter im Rückruf übergeben werden.
Ertrag und Generator können bei beiden helfen.
Ohne Ertrag und Generator erfordert das Aussortieren mehrerer asynchroner Abfragen einen verschachtelten Rückruf mit Parametern als Kontext, der nicht einfach zu lesen und zu warten ist.
Unten finden Sie ein Beispiel für verkettete asynchrone Abfragen, die mit nodejs ausgeführt werden:
Unten ist das laufende Ergebnis:
+++++++++++ Start ++++++++++++
query1 0
+++++++++++ Ende ++++++++++++
query2 1
query4 0
Das folgende Zustandsmuster kann das Gleiche für das obige Beispiel tun:
Es folgt das laufende Ergebnis:
+++++++++++ Start ++++++++++++
query1 0
+++++++++++ Ende ++++++++++++
query2 1
query4 0
quelle
Vergessen Sie nicht die sehr hilfreiche Syntax 'x des Generators', um den Generator zu durchlaufen. Die next () -Funktion muss überhaupt nicht verwendet werden.
quelle