| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Operators/await | [Back] [Original] |
Get to know MDN better
Cette page a t traduite partir de l'anglais par la communaut. Vous pouvez contribuer en rejoignant la communaut francophone sur MDN Web Docs.
Cette fonctionnalit est bien tablie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis mars 2017.
* Certaines parties de cette fonctionnalit peuvent bnficier de prise en charge variables.
L'oprateur await est utilis pour attendre une promesse (Promise) et obtenir sa valeur de compltion (fulfill en anglais). Il ne peut tre utilis qu' l'intrieur d'une fonction asynchrone ou au niveau suprieur d'un module.
await expression
expressionUne promesse (Promise), un objet de semi-promesse, ou toute autre valeur dont on souhaite attendre.
La valeur de compltion de la promesse ou de l'objet semi-promesse, ou, si l'expression n'est pas semi-promesse, la valeur propre de l'expression.
Lve la raison du rejet si la promesse ou l'objet semi-promesse est rompue (reject en anglais).
await est gnralement utilis pour dballer les promesses en passant une promesse (Promise) comme expression. L'utilisation de await suspend l'excution de la fonction async englobante jusqu' ce que la promesse soit acquitte (settle en anglais) (c'est--dire complte ou rompue). Lorsque l'excution reprend, la valeur de l'expression await devient celle de la promesse complte.
Si la promesse est rompue, l'expression await lve la valeur de rejet. La fonction contenant l'expression await apparat dans la trace de la pile de l'erreur. Sinon, si la promesse rompue n'est pas attendue ou est immdiatement retourne, la fonction appelante n'apparat pas dans la trace de la pile.
Une expression est rsolue de la mme manire que Promise.resolve() : elle est toujours convertie en une Promise native, puis attendue. Si une expression est :
Promise native (ce qui signifie que expression appartient Promise ou une sous-classe, et que expression.constructor === Promise) : la promesse est directement utilise et attendue nativement, sans appeler then().Promise() en appelant la mthode then() de l'objet et en passant un gestionnaire qui appelle la fonction de rappel resolve.Promise dj acquitte est construite et utilise.Mme lorsque la promesse utilise est dj acquitte, l'excution de la fonction asynchrone est toujours suspendue jusqu'au battement d'horloge suivant. Pendant ce temps, l'appelant de la fonction asynchrone reprend l'excution. Voir l'exemple ci-dessous.
Comme await n'est valide qu' l'intrieur des fonctions asynchrones et des modules, qui sont eux-mmes asynchrones et retournent des promesses, l'expression await ne bloque jamais le thread principal et ne fait que diffrer l'excution du code qui dpend rellement du rsultat, c'est--dire de tout ce qui se trouve aprs l'expression await.
Si une promesse (Promise) est passe une expression await, celle-ci attend que la promesse (Promise) soit complte et retourne la valeur complte.
function resoudreApres2Secondes(x) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function f1() {
const x = await resoudreApres2Secondes(10);
console.log(x); // 10
}
f1();
Les objets semi-promesses sont rsolus exactement de la mme manire que les vritables objets Promise.
async function f2() {
const objetSemiPromesse = {
then(resoudre) {
resoudre("rsolue !");
},
};
console.log(await objetSemiPromesse); // "rsolue !"
}
f2();
Ils peuvent galement tre rompus :
async function f2() {
const objetSemiPromesse = {
then(_, rejeter) {
rejeter(new Error("rompue !"));
},
};
await objetSemiPromesse; // Lve l'erreur Error : rompue !
}
f2();
Si la valeur n'est pas une Promise, await la convertit en une Promise complte et l'attend. L'identit de la valeur attendue ne change pas tant qu'elle ne possde pas de proprit then appelable.
async function f3() {
const y = await 20;
console.log(y); // 20
const obj = {};
console.log((await obj) === obj); // true
}
f3();
Si la promesse (Promise) est rompue, la valeur rompue est leve.
async function f4() {
try {
const z = await Promise.reject(new Error("rompue !"));
} catch (e) {
console.error(e); // Erreur : rompue !
}
}
f4();
Vous pouvez grer les promesses rompues sans bloc try en chanant un gestionnaire catch() avant d'attendre la promesse.
const reponse = await fonctionPromesse().catch((erreur) => {
console.error(erreur);
return "rponse par dfaut";
});
// reponse vaut rponse par dfaut si la promesse est rompue
Cette approche repose sur l'hypothse que fonctionPromesse() ne lve jamais d'erreur de manire synchrone, mais retourne toujours une promesse rompue. C'est le cas de la plupart des fonctions fondes sur les promesses et correctement conues, qui ressemblent gnralement ceci :
function fonctionPromesse() {
// Retourne immdiatement une promesse pour rduire le risque de lever une erreur
return new Promise((resoudre, rejeter) => {
// Effectuer une opration asynchrone
});
}
Cependant, si fonctionPromesse() lve une erreur de manire synchrone, le gestionnaire catch() ne l'intercepte pas. Dans ce cas, l'instruction try...catch est ncessaire.
await au niveau suprieurVous pouvez utiliser le mot-cl await seul, en dehors d'une fonction asynchrone, au niveau suprieur d'un module. Ainsi, les modules qui possdent des modules enfants utilisant await attendent l'excution de ces modules enfants avant de s'excuter eux-mmes, sans bloquer le chargement des autres modules enfants.
Voici un exemple de module qui utilise l'API Fetch (angl.) et dfinit await dans l'instruction export. Les modules qui incluent ce module attendent la rsolution de la requte avant d'excuter du code.
// Requte Fetch
const couleurs = fetch("../data/colors.json").then((reponse) => reponse.json());
export default await couleurs;
await sur le fluxLorsqu'un await est rencontr dans le code (soit dans une fonction asynchrone, soit dans un module), l'expression attendue est excute, tandis que tout le code qui dpend de la valeur de l'expression est mis en pause. Le contrle quitte la fonction et revient l'appelant. Lorsque la valeur de l'expression attendue est rsolue, une autre micro-tche qui continue le code en pause est planifie. Cela se produit mme si la valeur attendue est une promesse dj rsolue ou non : l'excution ne revient pas la fonction actuelle tant que toutes les autres micro-tches dj planifies ne sont pas traites. Par exemple, considrez le code suivant :
async function toto(nom) {
console.log(nom, "dbut");
console.log(nom, "milieu");
console.log(nom, "fin");
}
toto("Premire");
toto("Deuxime");
// Premire dbut
// Premire milieu
// Premire fin
// Deuxime dbut
// Deuxime milieu
// Deuxime fin
Dans ce cas, la fonction toto est synchrone en pratique, car elle ne contient aucune expression await. Les trois instructions s'excutent lors du mme cycle. Les deux appels de fonction excutent donc toutes les instructions dans l'ordre. En termes de promesses, la fonction correspond ceci :
function toto(nom) {
return new Promise((resoudre) => {
console.log(nom, "dbut");
console.log(nom, "milieu");
console.log(nom, "fin");
resoudre();
});
}
Cependant, ds qu'un await apparat, la fonction devient asynchrone et l'excution des instructions suivantes est reporte au cycle suivant.
async function toto(nom) {
console.log(nom, "dbut");
await console.log(nom, "milieu");
console.log(nom, "fin");
}
toto("Premire");
toto("Deuxime");
// Premire dbut
// Premire milieu
// Deuxime dbut
// Deuxime milieu
// Premire fin
// Deuxime fin
Cela correspond ceci :
function toto(nom) {
return new Promise((resoudre) => {
console.log(nom, "dbut");
resoudre(console.log(nom, "milieu"));
}).then(() => {
console.log(nom, "fin");
});
}
Le gestionnaire then() supplmentaire peut tre fusionn avec l'excuteur transmis au constructeur, car il n'attend aucune opration asynchrone. Cependant, sa prsence divise le code en une micro-tche supplmentaire pour chaque appel de toto. Ces micro-tches sont planifies et excutes de manire entrelace, ce qui peut ralentir votre code et introduire des conditions de concurrence inutiles. Utilisez donc await uniquement lorsque c'est ncessaire, pour dballer les promesses en leurs valeurs.
Les micro-tches sont planifies non seulement lors de la rsolution des promesses, mais aussi par d'autres API web, et elles s'excutent avec la mme priorit. Cet exemple utilise queueMicrotask() pour montrer comment la file des micro-tches est traite lorsqu'une expression await est rencontre.
let i = 0;
queueMicrotask(function tester() {
i++;
console.log("micro-tche", i);
if (i < 3) {
queueMicrotask(tester);
}
});
(async () => {
console.log("dbut de la fonction asynchrone");
for (let i = 1; i < 3; i++) {
await null;
console.log("reprise de la fonction asynchrone", i);
}
await null;
console.log("fin de la fonction asynchrone");
})();
queueMicrotask(() => {
console.log("queueMicrotask() aprs l'appel de la fonction asynchrone");
});
console.log("fin de la partie synchrone du script");
// Journalisation :
// dbut de la fonction asynchrone
// fin de la partie synchrone du script
// opration 1
// reprise de la fonction asynchrone 1
// queueMicrotask() aprs l'appel de la fonction asynchrone
// opration 2
// reprise de la fonction asynchrone 2
// opration 3
// fin de la fonction asynchrone
Dans cet exemple, la fonction test() est toujours appele avant la reprise de la fonction asynchrone. Les micro-tches qu'elles planifient sont donc toujours excutes de manire entrelace. En revanche, comme await et queueMicrotask() planifient tous deux des micro-tches, l'ordre d'excution dpend toujours de l'ordre de planification. C'est pourquoi le message queueMicrotask() aprs l'appel de la fonction asynchrone apparat aprs la premire reprise de la fonction asynchrone.
Parfois, await est omis lorsqu'une promesse est directement retourne par une fonction asynchrone.
async function sansAwait() {
// Certaines actions...
return /* await */ derniereTacheAsynchrone();
}
Cependant, prenons le cas o derniereTacheAsynchrone lve une erreur de manire asynchrone.
async function derniereTacheAsynchrone() {
await null;
throw new Error("chec");
}
async function sansAwait() {
return derniereTacheAsynchrone();
}
sansAwait();
// Erreur : chec
// derniereTacheAsynchrone
Seule derniereTacheAsynchrone apparat dans la trace de la pile, car la promesse est rompue aprs avoir dj t retourne par sansAwait : d'une certaine manire, la promesse n'est pas lie sansAwait. Pour amliorer la trace de la pile, vous pouvez utiliser await pour dballer la promesse afin que l'exception soit leve dans la fonction actuelle. L'exception est alors immdiatement enveloppe dans une nouvelle promesse rompue, mais l'appelant apparat dans la trace de la pile lors de la cration de l'erreur.
async function derniereTacheAsynchrone() {
await null;
throw new Error("chec");
}
async function avecAwait() {
return await derniereTacheAsynchrone();
}
avecAwait();
// Erreur : chec
// at derniereTacheAsynchrone
// at async avecAwait
Contrairement une ide rpandue, return await promise est au moins aussi rapide que return promise, grce l'optimisation de la rsolution des promesses natives par la spcification et les moteurs. Une proposition vise rendre return promise plus rapide (angl.), et vous pouvez galement lire l'article sur l'optimisation de V8 concernant les fonctions asynchrones (angl.). Ainsi, sauf pour des raisons stylistiques, return await est presque toujours prfrable.
| Spcification |
|---|
| ECMAScript 2027 LanguageSpecification # sec-async-function-definitions |
async functionasync functionAsyncFunctionawait de niveau suprieur (angl.) sur v8.dev (2019)return-await (angl.)Cette page a t modifie le 5 sept. 2026 par les contributeurices du MDN.
Certaines parties de ce contenu sont protges par le droit d'auteur 19982026 des contributeurs individuels de mozilla.org. Contenu disponible sous une licence Creative Commons.
| Web Proxy Viewer | New URL | Original Page |