[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Statements/async_function [Back]  [Original]

async function - JavaScript | MDN

Cette page a t traduite partir de l'anglais par la communaut. Vous pouvez contribuer en rejoignant la communaut francophone sur MDN Web Docs.

View in English Always switch to English

async function

Baseline Large disponibilit

Cette fonctionnalit est bien tablie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis avril 2017.

Une fonction asynchrone est une fonction prcde par le mot-cl async, et qui peut contenir le mot-cl await. async et await permettent un comportement asynchrone, bas sur une promesse (Promise), crite de faon simple, et vitant de configurer explicitement les chanes de promesse.

Les fonctions asynchrones peuvent galement tre dfinies comme des expressions.

Dans cet article

Exemple interactif

function resolveAfter2Seconds() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve("resolved");
    }, 2000);
  });
}

async function asyncCall() {
  console.log("calling");
  const result = await resolveAfter2Seconds();
  console.log(result);
  // Expected output: "resolved"
}

asyncCall();

Syntaxe

js
async function name([param[, param[, param]]]) {
  instructions
}

Paramtres

name

Le nom de la fonction.

param

Le nom d'un argument passer la fonction.

instructions

Les instructions qui composent le corps de la fonction.

Valeur de retour

Une promesse (Promise) qui sera rsolue avec la valeur renvoye par la fonction asynchrone ou qui sera rompue s'il y a une exception non intercepte mise depuis la fonction asynchrone.

Description

Une fonction async peut contenir une expression await qui interrompt l'excution de la fonction asynchrone et attend la rsolution de la promesse passe Promise. La fonction asynchrone reprend ensuite puis renvoie la valeur de rsolution.

Le mot-cl await est uniquement valide au sein des fonctions asynchrones. Si ce mot-cl est utilis en dehors du corps d'une fonction asynchrone, cela provoquera une exception SyntaxError.

Note : Lorsqu'une fonction asynchrone est mise en pause, la fonction appelante continue son excution (car elle a reu la promesse implicite renvoye par la fonction async).

Note : Le but des fonctions async/await est de simplifier l'utilisation synchrone des promesses et d'oprer sur des groupes de promesses. De la mme faon que les promesses sont semblables des callbacks structurs, async/await est semblable la combinaison des gnrateurs et des promesses.

Exemples

Exemple simple

js
var resolveAfter2Seconds = function () {
  console.log("Initialisation de la promesse lente");
  return new Promise((resolve) => {
    setTimeout(function () {
      resolve("lente");
      console.log("La promesse lente est termine");
    }, 2000);
  });
};

var resolveAfter1Second = function () {
  console.log("Initialisation de la promesse rapide");
  return new Promise((resolve) => {
    setTimeout(function () {
      resolve("rapide");
      console.log("La promesse rapide est termine");
    }, 1000);
  });
};

var sequentialStart = async function () {
  console.log("==Dbut squentiel==");

  // 1. L'excution atteint ce point quasi-instantanment
  const lente = await resolveAfter2Seconds();
  console.log(lente); // 2. cela s'excute 2s aprs 1.

  const rapide = await resolveAfter1Second();
  console.log(rapide); // 3. cela s'excute 3s aprs 1.
};

var concurrentStart = async function () {
  console.log("==Dbut concurrentiel avec await==");
  const lente = resolveAfter2Seconds(); // le minuteur dmarre immdiatement
  const rapide = resolveAfter1Second(); // le minuteur dmarre immdiatement

  // 1. L'excution atteint ce point quasi-instantanment
  console.log(await lente); // 2. s'excute 2s aprs 1.
  console.log(await rapide); // 3. s'excute 2s aprs 1., immdiatement aprs 2.,
  // car "rapide" est dj rsolue
};

var concurrentPromise = function () {
  console.log("==Dbut concurrentiel avec Promise.all==");
  return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then(
    (messages) => {
      console.log(messages[0]); // lente
      console.log(messages[1]); // rapide
    },
  );
};

var parallel = async function () {
  console.log("==Excution parallle avec await Promise.all==");

  // Dmarre 2 tches en parallle et on attend que les deux soient finies
  await Promise.all([
    (async () => console.log(await resolveAfter2Seconds()))(),
    (async () => console.log(await resolveAfter1Second()))(),
  ]);
};

// Cette fonction ne gre pas les erreurs
// voir les avertissement ci-aprs !
var parallelPromise = function () {
  console.log("==Excution parallle avec Promise.then==");
  resolveAfter2Seconds().then((message) => console.log(message));
  resolveAfter1Second().then((message) => console.log(message));
};

sequentialStart(); // aprs 2 secondes, "lente" est affiche, aprs une
// autre seconde, c'est "rapide" qui est affiche

// on attend que l'tape prcdente soit termine
setTimeout(concurrentStart, 4000); // 2s avant d'afficher "lente" puis "rapide"

// on attend  nouveau
setTimeout(concurrentPromise, 7000); // identique  concurrentStart

// on attend  nouveau
setTimeout(parallel, 10000); // rellement parallele : aprs 1 seconde,
// affiche "rapide" et aprs une autre seconde
// affiche "lente"

// on attend  nouveau
setTimeout(parallelPromise, 13000); // identique  parallel

await et l'excution parallle

Dans sequentialStart, l'excution est arrte pendant deux secondes avant le premier await puis encore une autre seconde avant le deuxime await. Le deuxime minuteur n'est pas cr tant que le premier n'est pas coul. Le code s'excute donc au moins en 3 secondes.

Avec concurrentStart, les deux minuteurs sont crs puis attendus derrire un await Les minuteurs sont excuts de faon concurrente. L'ensemble du code se termine donc en au moins 2 secondes plutt qu'en 3 secondes. Toutefois, les appels utilisant await sont excuts squentiellement et la deuxime instruction avec await attendra que la premire ait t traite. Le minuteur le plus rapide est donc cr juste aprs le premier.

Si on souhaite avoir deux tches qui s'excutent rellement en parallle, on pourra utiliser await Promise.all([job1(), job2()]) comme illustr ci-avant avec parallel.

async/await, Promise.prototype.then() et la gestion des erreurs

La plupart des fonctions asynchrones peuvent tre crites avec des promesses. Toutefois, les fonctions asynchrones qui utilisent async se prtent mieux la gestion des erreurs.

concurrentStart et concurrentPromise sont fonctionnellement quivalentes. Avec concurrentStart, si l'un des deux appels choue, l'exception sera immdiatement intercepte et l'excution de la fonction asynchrone sera interrompue. L'erreur sera propage la fonction appelante via la valeur de retour qui est une promesse implicite. Pour obtenir les mmes scurits avec les promesses, il faut s'assurer que la fonction renvoie une promesse qui gre ce cas d'chec. Pour concurrentPromise cela signifie qu'il faut renvoyer la promesse de Promise.all([]).then().

Bien entendu, il est toutefois possible d'avoir des fonctions asynchrones (avec async) qui gobent des erreurs involontairement. Si on considre la fonction parallel ci-avant, s'il n'y avait eu aucun await ou return pour le rsultat de Promise.all([]), aucune erreur n'aurait t propage. Bien que l'exemple parallelPromise paraisse simple, il ne gre aucune erreur du tout. Il aurait fallu utiliser un return Promise.all([]) analogue.

Rcrire une chane de promesses avec une fonction asynchrone

Lorsqu'on utilise une API qui renvoie des promesses (Promise), on construit une chane de promesses et on divise la fonction en de nombreuses branches :

js
function getProcessedData(url) {
  return downloadData(url) // renvoie une promesse
    .catch((e) => {
      return downloadFallbackData(url); // renvoie une promesse
    })
    .then((v) => {
      return processDataInWorker(v); // renvoie une promesse
    });
}

Cela peut tre rcrit avec une seule fonction asynchrone, de la faon suivante :

js
async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url);
  } catch (e) {
    v = await downloadFallbackData(url);
  }
  return processDataInWorker(v);
}

On voit dans l'exemple prcdent qu'il n'y a pas de await pour l'instruction return car la valeur de retour d'une fonction asynchrone est implicitement enveloppe dans un appel Promise.resolve.

Diffrences entre return et return await

La conversion automatique des valeurs en promesses avec Promise.resolve ne signifie pas que return await valeurPromesse sera quivalent return valeurPromesse.

Si on reprend l'exemple prcdent et qu'on le rcrit avec return await et qu'on intercepte une ventuelle erreur de la promesse :

js
async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url);
  } catch (e) {
    v = await downloadFallbackData(url);
  }
  try {
    return await processDataInWorker(v); // et non plus simplement return
  } catch (e) {
    return null;
  }
}

Si on avait simplement crit return processDataInWorker(v);, la promesse renvoye par la fonction aurait dclench une exception plutt que d'tre rsolue avec la valeur null.

Lorsqu'on utilise return toto;, la valeur toto sera immdiatement renvoye (sans lever d'exception, quel que soit le cas), tandis que return await toto; attendra la rsolution de toto ou son chec et lvera une exception si besoin avant de parvenir renvoyer une valeur.

Spcifications

Spcification
ECMAScript 2027 LanguageSpecification
# sec-async-function-definitions

Compatibilit des navigateurs

Voir aussi


Web Proxy Viewer  |  New URL  |  Original Page