La spécification provisoire d'ECMAScript 6 a déjà apporté de nombreuses sources de joie aux développeurs JavaScript modernes. Dans un post précédent, nous avons abordé de nouvelles classes de collections et des boucles d'itération for..of
. Dans cet article, nous allons parler d'un élément qui va de pair avec les boucles for..of
: les fonctions génératrices.
De nombreux excellents contenus sont déjà disponibles pour expliquer pourquoi et comment utiliser des générateurs. En résumé, les générateurs sont des fonctions spéciales qui créent des itérateurs. Les itérateurs sont des objets qui disposent d'une méthode next()
, qui peut être appelée pour obtenir une valeur. Dans une fonction génératrice, le mot clé yield
fournit la valeur pour next()
. L'utilisation de yield
suspend l'exécution de la fonction génératrice, en conservant l'état jusqu'à ce que next()
soit appelé à nouveau, auquel cas le code redémarre et continue jusqu'à ce qu'il yield
une autre valeur (ou jusqu'à ce que la fonction génératrice se termine). Il existe plusieurs cas d'utilisation canoniques des fonctions génératrices, par exemple pour itérer sur les nombres de la séquence de Fibonacci.
Maintenant que vous connaissez les principes de base, examinons en détail un exemple JavaScript qui couvre certains des pièges de l'utilisation des générateurs. Le code est accompagné de commentaires détaillés. Vous pouvez tester la version en direct du code avant de le lire:
Quels sont les principaux points à retenir du code ?
Tout d'abord, la création d'un générateur génère un itérateur unique avec son propre état distinct. Vous pouvez transmettre des paramètres au constructeur du générateur qui peuvent contrôler son comportement.
Deuxièmement, vous pouvez transmettre un paramètre lorsque vous appelez la méthode next()
d'un itérateur. Cette valeur sera attribuée à tout ce qui se trouve à gauche de l'instruction yield
de l'appel d'itérateur précédent. C'est un excellent moyen de faire varier la sortie de l'itérateur. Ici, nous l'utilisons pour contrôler si le mot généré est en majuscules ou non. Si vous souhaitez influencer la toute première valeur générée, faites-le via un paramètre du constructeur du générateur.
Enfin, les générateurs peuvent produire des itérateurs finis ou infinis. Si vous utilisez un itérateur infini, assurez-vous d'avoir une sorte de condition terminale basée sur la valeur yield
. Il est très facile d'écrire accidentellement des boucles infinies, en particulier lorsque vous utilisez for..of
pour l'itération. Si vous utilisez un itérateur fini via des appels à next()
, la propriété .done
de l'objet renvoyé indique si l'itération est terminée.
Nous espérons que cet exemple, ainsi que les autres ressources disponibles sur le Web, vous donneront envie d'utiliser des générateurs dans votre propre code. Les versions de Firefox à partir de la 31 et de Chrome à partir de la 39 sont compatibles avec les générateurs en mode natif. Le projet Regenerator est compatible avec d'autres navigateurs. Vous pouvez également utiliser Traceur.
Merci à Erik Arvidsson pour son aide à la relecture de cet article.