function*
Déclare un générateur : une fonction qui livre des valeurs successives via yield et se met en pause entre elles.
- Renvoie
- L’appel d’une fonction génératrice renvoie un objet générateur, qui est à la fois un itérateur et un objet itérable.
Exemple
#function* lessonSteps() {
yield 'Vidéo'
yield 'Théorie'
yield 'Quiz'
}
const steps = lessonSteps()
console.log(steps.next())
console.log(steps.next())
console.log(steps.next())
console.log(steps.next())Définition et utilisation
#Une fonction écrite comme function* est un générateur. Son appel ne lance pas le code immédiatement, il renvoie seulement un objet générateur. Le code ne démarre qu’après l’appel de next(), et s’exécute jusqu’au prochain yield, qui livre une valeur et arrête la fonction à cet endroit. Le next() suivant reprend le travail exactement là où il s’était arrêté.
Chaque next() renvoie un objet { value, done }. Tant que le générateur atteint de nouveaux yield, le champ done vaut false. Quand la fonction termine son exécution ou rencontre un return, vous obtenez done: true. Le générateur est un objet itérable, donc vous pouvez le parcourir avec for...of, le décomposer avec le spread [...gen] ou le passer à Array.from().
Les générateurs calculent les valeurs de façon paresseuse, c’est-à-dire seulement quand elles sont nécessaires. Grâce à cela, ils peuvent décrire même des suites infinies, par ex. des identifiants successifs, sans occuper de mémoire. yield* transmet toutes les valeurs d’un autre objet itérable, et async function* crée un générateur asynchrone, que l’on parcourt avec la boucle for await...of.
Syntaxe
#function* name(params) {
yield value
yield* iterable
return finalValue
}
const generator = name()
generator.next()Plus d’exemples
#function* range(start, end, step = 1) {
for (let i = start; i <= end; i += step) {
yield i
}
}
for (const level of range(1, 3)) {
console.log(`Niveau ${level}`)
}
console.log([...range(0, 20, 5)])function* createIds(prefix) {
let id = 1
while (true) {
yield `${prefix}-${id}`
id++
}
}
const taskIds = createIds('task')
console.log(taskIds.next().value)
console.log(taskIds.next().value)
console.log(taskIds.next().value)La boucle while (true) ne bloque pas le programme, car le générateur s’arrête à chaque yield et attend le prochain appel de next().
function* frontend() {
yield 'HTML'
yield 'CSS'
}
function* fullStack() {
yield* frontend()
yield 'JavaScript'
yield* ['Node.js', 'SQL']
}
console.log([...fullStack()])Compatibilité des navigateurs
#Largement disponible
Fonctionne dans tous les navigateurs modernes, y compris sur mobile. Vous pouvez l’utiliser sans crainte.
- Chrome
- Edge
- Firefox
- Safari
Bonnes pratiques
#- On ne peut parcourir un générateur qu’une seule fois. Quand vous avez besoin des valeurs à nouveau, appelez encore la fonction génératrice ou enregistrez les résultats dans un tableau.
- La valeur d’un
returnadone: true, donc la bouclefor...ofet le spread l’ignorent. Tout ce qui doit se retrouver dans le résultat doit être livré paryield. - Ne décomposez pas un générateur infini avec le spread ni avec
Array.from(). Récupérez ses valeurs avecnext()ou interrompez la boucle avecbreak.
Entrées associées
#- Itérateurs (Symbol.iterator)Le protocole d’itération : un objet avec une méthode [Symbol.iterator]() fonctionne avec for...of, le spread et la déstructuration.
- for...ofParcourt les valeurs successives d’un objet itérable : tableau, chaîne, Map, Set et autres.
- functionDéclare une fonction nommée : un bloc de code avec des paramètres, que vous pouvez appeler autant de fois que vous voulez et qui peut renvoyer un résultat.
- Spread (...)La syntaxe spread décompose un tableau, une chaîne ou un objet en éléments individuels : pour copier, fusionner et passer des arguments.
- returnTermine l’exécution d’une fonction et transmet une valeur à l’endroit où la fonction a été appelée.
Vous voyez une erreur ou il manque un exemple ? Écrivez-nous.