Fonctions génératrices en TypeScript

Fonctions génératrices en TypeScript

Cet article explique les fonctions génératrices en TypeScript.

Vous pouvez apprendre tout, des bases de l'utilisation des fonctions génératrices aux exemples avancés combinés avec le traitement asynchrone, accompagnés d'exemples de code.

YouTube Video

Fonctions génératrices

Les fonctions génératrices en TypeScript offrent une fonctionnalité similaire à celle des fonctions génératrices en JavaScript. Les fonctions génératrices sont définies à l'aide de function* (une déclaration de fonction avec un astérisque) et sont des fonctions spéciales pouvant suspendre et reprendre leur exécution, à la différence des fonctions normales.

Lorsqu'une fonction génératrice est appelée, un itérateur est retourné, qui génère des valeurs une à une via cet itérateur. Vous pouvez suspendre l'exécution à l'aide du mot-clé yield ou envoyer des valeurs depuis l'extérieur.

Syntaxe de base des fonctions génératrices

 1function* myGenerator(): Generator<number, void, unknown> {
 2    yield 1;
 3    yield 2;
 4    yield 3;
 5}
 6
 7const gen = myGenerator();
 8
 9console.log(gen.next().value); // 1
10console.log(gen.next().value); // 2
11console.log(gen.next().value); // 3
12console.log(gen.next().done);  // true (Iteration finished)
  • Définissez une fonction génératrice avec function* myGenerator().
  • Le mot-clé yield suspend l'exécution de la fonction tout en retournant une valeur.
  • Chaque fois que la méthode next() est appelée, l'exécution de la fonction génératrice reprend et passe au prochain yield.

next() retourne un objet contenant la prochaine valeur et une propriété done. Quand done est à true, cela indique que toutes les valeurs ont été générées et que le traitement du générateur est terminé.

Applications des fonctions génératrices

L'utilisation des fonctions génératrices permet une représentation facile des traitements séquentiels. Dans l'exemple suivant, nous créons une fonction génératrice qui génère une séquence de nombres.

 1function* sequenceGenerator(start: number = 0, step: number = 1) {
 2    let current = start;
 3    while (true) {
 4        yield current;
 5        current += step;
 6    }
 7}
 8
 9const seq = sequenceGenerator(1, 2);
10
11console.log(seq.next().value); // 1
12console.log(seq.next().value); // 3
13console.log(seq.next().value); // 5
  • Dans cet exemple, sequenceGenerator génère une séquence de nombres croissante indéfiniment. Utilisez yield pour retourner des valeurs à chaque étape et générez la valeur suivante lors des appels successifs.

Passer des valeurs à next

La méthode next() peut recevoir une valeur qui peut être envoyée dans la fonction génératrice.

 1function* adder() {
 2    const num1 = yield;
 3    const num2 = yield;
 4    yield num1 + num2;
 5}
 6
 7const addGen = adder();
 8addGen.next();          // Initialization
 9addGen.next(5);         // Set 5 to num1
10const result = addGen.next(10).value; // Set 10 to num2 and get result
11console.log(result);    // 15
  • Dans cet exemple, next(5) et next(10) envoient leurs valeurs respectives dans la fonction génératrice, et yield num1 + num2 retourne leur somme.

return et throw

  • return(value) peut terminer le générateur et retourner la valeur spécifiée.
  • throw(error) peut lancer une exception dans le générateur, utilisée pour gérer les exceptions à l'intérieur du générateur.
 1function* testGenerator() {
 2    try {
 3        yield 1;
 4        yield 2;
 5    } catch (e) {
 6        console.error("Error caught:", e);
 7    }
 8}
 9
10const gen = testGenerator();
11console.log(gen.next().value); // 1
12gen.throw(new Error("An error occurred!")); // Error caught: An error occurred!
  • Dans cet exemple, la méthode throw est utilisée pour générer une erreur dans le générateur, et cette erreur est interceptée à l'intérieur du générateur.

Définition de type en TypeScript

La définition de type d'une fonction génératrice peut être spécifiée dans le format suivant.

1// Generator<YieldType, ReturnType, NextType>
2function* myGenerator(): Generator<number, void, unknown> {
3    yield 1;
4    yield 2;
5    yield 3;
6}
  • Vous indiquez les types sous la forme Generator<YieldType, ReturnType, NextType>.
    • YieldType est le type de la valeur renvoyée par yield.
    • ReturnType est le type de la valeur renvoyée par return.
    • NextType est le type de la valeur transmise à next().

Dans l'exemple suivant, des types spécifiques sont définis pour utiliser le générateur de manière sûre avec des types.

 1function* numberGenerator(): Generator<number, void, number> {
 2    const num1 = yield 1;
 3    const num2 = yield num1 + 2;
 4    yield num2 + 3;
 5}
 6
 7const gen = numberGenerator();
 8
 9console.log(gen.next().value);   // 1
10console.log(gen.next(10).value); // 12 (10 + 2)
11console.log(gen.next(20).value); // 23 (20 + 3)

Générateurs et traitement asynchrone

Les générateurs peuvent également être utilisés pour le traitement asynchrone. Par exemple, vous pouvez utiliser yield pour attendre les résultats des opérations asynchrones tout en continuant le traitement séquentiel. Cependant, en TypeScript ou JavaScript, async/await est plus couramment utilisé.

1function* asyncTask() {
2    const result1 = yield fetch("https://codesparklab.com/json/example1.json");
3    console.log(result1);
4
5    const result2 = yield fetch("https://codesparklab.com/json/example2.json");
6    console.log(result2);
7}

Ainsi, bien que vous puissiez traiter les opérations asynchrones de manière séquentielle avec des générateurs, ils ne sont pas couramment utilisés pour le traitement asynchrone, car les Promises et async/await sont plus pratiques.

Résumé

  • Les fonctions génératrices sont des fonctions spéciales définies avec function* qui peuvent retourner des valeurs avec yield tout en mettant en pause l'exécution de la fonction.
  • Utilisez next() pour reprendre le générateur et recevoir des valeurs. De plus, vous pouvez envoyer des valeurs au générateur en utilisant next(value).
  • Vous pouvez utiliser return() et throw() pour terminer les fonctions génératrices ou gérer les erreurs.
  • Lorsque vous utilisez des générateurs en TypeScript, vous pouvez utiliser des définitions de type pour écrire un code type-safe.

Les générateurs sont des outils puissants qui vous permettent de contrôler de manière flexible l'itération.

Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.

YouTube Video