async function*

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.

Une déclaration async function* définit une fonction génératrice asynchrone, qui renvoie un objet AsyncGenerator.

Exemple interactif

Il est aussi possible de définir des fonctions génératrices asynchrones à l'aide du constructeur AsyncGeneratorFunction() ou d'une expression async function*.

Syntaxe

js
async function* nom(param0) {
  instructions;
}
async function* nom(param0, param1) {
  instructions;
}
async function* nom(param0, param1, /* … ,*/ paramN) {
  instructions;
}

Note : Il n'existe pas de notation équivalente aux fonctions fléchées pour les fonctions génératrices asynchrones.

Paramètres

nom

Le nom de la fonction.

param Facultatif

Le nom d'un paramètre formel pour la fonction.

instructions Facultatif

Les instructions formant le corps de la fonction.

Description

Une fonction génératrice asynchrone combine les fonctionnalités des fonctions asynchrones et des fonctions génératrices. Les deux mots-clés await et yield peuvent être utilisés dans le corps d'une telle fonction. Cela permet de gérer des tâches asynchrones de façon concise avec await, tout en profitant de l'exécution à la demande permise par les fonctions génératrices.

À la différence des fonctions génératrices normales déclarées avec function*, une fonction génératrice asynchrone renvoie un objet AsyncGenerator qui suit le protocole itérable asynchrone. Chaque appel à next() renvoie une promesse qui est résolue avec l'objet résultant de l'itérateur.

Lorsqu'une promesse est déclenchée depuis un générateur asynchrone, l'état de la promesse qui est le résultat de l'itérateur correspondra à celui de la promesse déclenchée. On aura par exemple :

js
async function* toto() {
  yield Promise.reject(1);
}

toto()
  .next()
  .catch((e) => console.error(e));

Qui affichera 1 dans la console, car la promesse ainsi générée déclenche une erreur et le résultat dans l'itérateur déclenche une erreur également. La propriété value du résultat d'un générateur asynchrone résolu ne sera pas une autre promesse.

Exemples

Déclarer une fonction génératrice asynchrone

Les fonctions génératrices asynchrones produisent toujours des promesses comme résultat, même si chaque étape yield est synchrone.

js
async function* monGenerateur(etape) {
  await new Promise((resolve) => setTimeout(resolve, 10));
  yield 0;
  yield etape;
  yield etape * 2;
}

const gen = monGenerateur(2);
gen
  .next()
  .then((res) => {
    console.log(res); // { value: 0, done: false }
    return gen.next();
  })
  .then((res) => {
    console.log(res); // { value: 2, done: false }
    return gen.next();
  })
  .then((res) => {
    console.log(res); // { value: 4, done: false }
    return gen.next();
  })
  .then((res) => {
    console.log(res); // { value: undefined, done: true }
    return gen.next();
  });

Utiliser une fonction génératrice asynchrone afin de lire un ensemble de fichiers

Dans cet exemple, on lit une suite de fichiers en accédant à leur contenu uniquement lorsqu'on le demande, en utilisant le module Node.js fs/promises.

js
async function* readFiles(directory) {
  const files = await fs.readdir(directory);
  for (const file of files) {
    const stats = await fs.stat(file);
    if (stats.isFile()) {
      yield {
        name: file,
        content: await fs.readFile(file, "utf8"),
      };
    }
  }
}

const files = readFiles(".");
console.log((await files.next()).value);
// Exemple de sortie : { name: 'fichier1.txt', content: '...' }
console.log((await files.next()).value);
// Exemple de sortie : { name: 'fichier2.txt', content: '...' }

Spécifications

Specification
ECMAScript Language Specification
# sec-async-generator-function-definitions

Compatibilité des navigateurs

BCD tables only load in the browser

Voir aussi