Cette page a été traduite à partir de l'anglais par la communauté.Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.
function*
Baseline Widely available
Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis septembre 2016.
La déclarationfunction* (le mot-cléfunction suivi par un astérisque) permet de définir un générateur (aussi appelé une fonction génératrice) (un générateur est un objetGenerator).
Dans cet article
Exemple interactif
function* generator(i) { yield i; yield i + 10;}const gen = generator(10);console.log(gen.next().value);// Expected output: 10console.log(gen.next().value);// Expected output: 20Il est également possible de définir un générateur en utilisant le constructeurGeneratorFunction et une expressionfunction*.
Syntaxe
function* nom([param1[, param2[, … paramN]]]) { instructions}nomLe nom de la fonction.
paramNLe nom d'un paramètre formel passé à la fonction.
instructionsLes instructions qui constituent le corps de la fonction.
Description
Les générateurs sont des fonctions qu'il est possible de quitter puis de reprendre. Le contexte d'un générateur (les liaisons avec ses variables) est sauvegardé entre les reprises successives.
Les générateurs, combinés avecles promesses, sont des outils de programmation asynchrones puissants qui permettent de réduire les inconvénients causés par lescallbacks (fonctions de rappel) etl'inversion de contrôle.
Lorsqu'on appelle une fonction génératrice, son corps n'est pas exécuté immédiatement, c'est unitérateur qui est renvoyé pour la fonction. Lorsque la méthodenext() de l'itérateur est appelée, le corps de la fonction génératrice est utilisé jusqu'à ce que la première expressionyield soit trouvée. Cette expression définira la valeur à renvoyer pour l'itérateur. Si on utiliseyield*, on pourra déléguer la génération des valeurs à une autre fonction génératrice. La méthodenext() renvoie un objet dont la propriétévalue contient la valeur générée et une propriétédone qui indique si le générateur a produit sa dernière valeur ou non. Lorsqu'on appelle la méthodenext() avec un argument, cela reprendra l'exécution de la fonction génératrice et remplacera la valeur de l'expressionyield (là où l'exécution avait été interrompue) avec la valeur de l'argument passé ànext().
On peut utiliser une instructionreturn dans un générateur. Lorsque cette instruction sera exécutée, le générateur sera terminé (done vaudratrue). La valeur renvoyée par l'instructionreturn sera la valeur de terminaison du générateur. Une fois qu'un générateur est terminé, il ne peut plus produire d'autres valeurs.
À l'instar d'une instructionreturn, une exception levée à l'intérieur du générateur entraînera la terminaison du générateur sauf si cette exception est interceptée. Lorsqu'un générateur est terminé, les appels suivants ànext() n'exécuteront aucun code provenant du générateur, ils renverront simplement un objet de la forme{value: undefined, done: true}.
Exemples
>Exemple simple
function* creerID() { var index = 0; while (true) { yield index++; }}var gen = creerID();console.log(gen.next().value); // 0console.log(gen.next().value); // 1console.log(gen.next().value); // 2console.log(gen.next().value); // 3Exemple utilisant des arguments
function* logGenerator() { console.log(yield); console.log(yield); console.log(yield);}var gen = logGenerator();// le premier appel à next exécute la fonction depuis son// début jusqu'au premier yield rencontrégen.next();gen.next("bretzel"); // bretzelgen.next("california"); // californiagen.next("mayonnaise"); // mayonnaiseExemple utilisant yield*
function* autreGenerateur(i) { yield i + 1; yield i + 2; yield i + 3;}function* generateur(i) { yield i; yield* autreGenerateur(i); yield i + 10;}var gen = generateur(10);console.log(gen.next().value); // 10console.log(gen.next().value); // 11console.log(gen.next().value); // 12console.log(gen.next().value); // 13console.log(gen.next().value); // 20Utilisation dereturn
function* yieldAndReturn() { yield "Y"; return "R"; yield "inaccessible";}var gen = yieldAndReturn();console.log(gen.next()); // { value: "Y", done: false }console.log(gen.next()); // { value: "R", done: true }console.log(gen.next()); // { value: undefined, done: true }Utiliser un générateur comme propriété
const monObj = { *generator() { yield "a"; yield "b"; },};const gen = monObj.generator();console.log(gen.next()); // { value: "a", done: false }console.log(gen.next()); // { value: "b", done: false }console.log(gen.next()); // { value: undefined, done: true }Utiliser un générateur comme propriété calculée
class Toto { *[Symbol.iterator]() { yield 1; yield 2; }}const monObj = { *[Symbol.iterator]() { yield "a"; yield "b"; },};console.log(Array.from(new Toto())); // [1, 2]console.log(Array.from(monObj)); // [ "a", "b"]Les générateurs ne sont pas constructibles
function* f() {}var obj = new f(); // lève une TypeError: f n'est pas un constructeurGénérateur défini avec une expression
const toto = function* () { yield 10; yield 20;};const truc = toto();console.log(truc.next()); // {value: 10, done: false}Spécifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-generator-function-definitions> |
Compatibilité des navigateurs
Voir aussi
- L'expression
function* - L'objet
GeneratorFunction - itérateur
yieldyield*- L'objet
Function - Les déclarations de fonction
- Les expressions de fonction
- Les fonctions
- D'autres ressources disponibles sur le Web :
- Regenerator un compilateur permettant de traduire des générateurs ES2015 en du code JavaScript basé sur ES5
- Forbes Lindesay: Promises and Generators: control flow utopia — JSConf EU 2013 (vidéo en anglais)
- Task.js
- Itérer de façon asynchrone sur des générateurs