Generatoren – die gnadenhaften Bits

Jens Posnick
Jeff Posnick

Der Entwurf der ECMAScript 6-Entwurfsspezifikation hat dem modernen JavaScript-Entwickler bereits viele Freude gemacht. In einem vorherigen Beitrag haben wir einige neue Sammelklassen und for..of-Iterationsschleifen behandelt. In diesem Beitrag geht es um etwas, das mit for..of-Schleifen Hand in Hand geht: Generatorfunktionen.

Es gibt bereits eine ganze Reihe großartiger Materialien, in denen erklärt wird, warum und wie man Generatoren nutzt. Kurz gesagt: Generatoren sind spezielle Funktionen, die Iterators erstellen. Iterationen sind Objekte mit einer next()-Methode, die aufgerufen werden kann, um einen Wert zu erhalten. Innerhalb einer Generatorfunktion liefert das Keyword yield den Wert für next(). Bei Verwendung von yield wird die Ausführung der Generatorfunktion sperrt. Dabei wird der Status beibehalten, bis next() noch einmal aufgerufen wird. Zu diesem Zeitpunkt startet der Code wieder und wird fortgesetzt, bis ein anderer Wert yield ausgegeben wird (oder bis die Generatorfunktion beendet wird). Es gibt mehrere kanonische Anwendungsfälle für Generatorfunktionen, z. B. die Verwendung von Generatorfunktionen zur Iteration über die Zahlen in der Fibonacci-Folge.

Nachdem die Grundlagen gelöst sind, sehen wir uns jetzt ein JavaScript-Beispiel an, das einige der schwierigen Dinge bei der Arbeit mit Generatoren abdeckt. Es gibt zahlreiche Kommentare und Sie können die Live-Version des Codes ausprobieren, bevor Sie ihn durchlesen:

Was sind also die wichtigsten Erkenntnisse aus dem Code?

Erstens führt die Erstellung eines Generators zu einem eindeutigen Iterator mit einem eigenen eindeutigen Status. Sie können dann Parameter an den Generator-Konstruktor übergeben, mit denen das Verhalten gesteuert werden kann.

Zweitens können Sie einen Parameter übergeben, wenn Sie die next()-Methode eines Iterators aufrufen. Dieser Wert wird dann dem linken Teil der yield-Anweisung des vorherigen Iterationsaufrufs zugewiesen. Dies ist eine großartige Möglichkeit, die Ausgabe des Iterationstests zu variieren. Hier verwenden wir ihn, um zu steuern, ob das Wort, das ausgegeben wird, in Großbuchstaben geschrieben wird oder nicht. Wenn Sie den allerersten Wert beeinflussen möchten, tun Sie dies über einen -Parameter für den Konstruktor des Generators.

Schließlich können Generatoren endliche oder unendliche Iterationen erzeugen. Wenn Sie mit einem unendlichen Iterator arbeiten, muss eine Endbedingung auf dem Wert yielded basieren. Es ist sehr leicht, versehentlich Endlosschleifen zu schreiben, insbesondere wenn for..of für die Iteration verwendet wird. Wenn Sie mit einem endlichen Iteration über Aufrufe von next() arbeiten, signalisiert das Attribut .done des zurückgegebenen Objekts, ob die Iteration abgeschlossen ist.

Wir hoffen, dass dieses Beispiel zusammen mit den anderen Ressourcen, die im Web verfügbar sind, Interesse weckt und Sie darüber nachdenkt, wie Sie Generatoren in Ihrem eigenen Code verwenden können. Die Versionen von Firefox ab Version 31 und Versionen von Chrome ab Version 39 unterstützen Generatoren nativ. Das Regenerator-Projekt bietet Generator-Unterstützung für andere Browser und die Verwendung von Traceur ist ebenfalls eine Option.

Vielen Dank an Erik Arvidsson für die Hilfe bei der Überprüfung dieses Artikels.