From bf8e099b9c8b3c60d60b3712b4fc97b052c39887 Mon Sep 17 00:00:00 2001 From: julieng Date: Tue, 3 Aug 2021 08:03:23 +0200 Subject: convert content to md --- .../reference/statements/async_function/index.md | 199 +++++++++------------ 1 file changed, 88 insertions(+), 111 deletions(-) (limited to 'files/fr/web/javascript/reference/statements/async_function') diff --git a/files/fr/web/javascript/reference/statements/async_function/index.md b/files/fr/web/javascript/reference/statements/async_function/index.md index 02131e514b..4c068e174e 100644 --- a/files/fr/web/javascript/reference/statements/async_function/index.md +++ b/files/fr/web/javascript/reference/statements/async_function/index.md @@ -10,59 +10,51 @@ tags: translation_of: Web/JavaScript/Reference/Statements/async_function original_slug: Web/JavaScript/Reference/Instructions/async_function --- -
{{jsSidebar("Statements")}}
+{{jsSidebar("Statements")}} -

La déclaration async function définit une fonction asynchrone qui renvoie un objet {{jsxref("Objets_globaux/AsyncFunction","AsyncFunction")}}. Une fonction asynchrone est une fonction qui s'exécute de façon asynchrone grâce à la boucle d'évènement en utilisant une promesse ({{jsxref("Promise")}}) comme valeur de retour.

+La déclaration **`async function`** définit une fonction asynchrone qui renvoie un objet {{jsxref("Objets_globaux/AsyncFunction","AsyncFunction")}}. Une fonction asynchrone est une fonction qui s'exécute de façon asynchrone grâce à la boucle d'évènement en utilisant une promesse ({{jsxref("Promise")}}) comme valeur de retour. -
-

On peut également définir des fonctions asynchrones grâce au constructeur {{jsxref("AsyncFunction")}} et via une {{jsxref("Opérateurs/async_function", "expression de fonction asynchrone","",1)}}.

-
+On peut également définir des fonctions asynchrones grâce au constructeur {{jsxref("AsyncFunction")}} et via une {{jsxref("Opérateurs/async_function", "expression de fonction asynchrone","",1)}}. -
{{EmbedInteractiveExample("pages/js/statement-async.html", "taller")}}
+{{EmbedInteractiveExample("pages/js/statement-async.html", "taller")}} -

Syntaxe

+## Syntaxe -
async function name([param[, param[, ... param]]]) {
-   instructions
-}
-
+ async function name([param[, param[, ... param]]]) { + instructions + } + +### Paramètres -

Paramètres

+- `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. -
-
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 -

Valeur de retour

+Une promesse ({{jsxref("Promise")}}) qui sera résolue avec la valeur renvoyée par la fonction asynchrone ou qui sera rompue s'il y a une exception non interceptée émise depuis la fonction asynchrone. -

Une promesse ({{jsxref("Promise")}}) qui sera résolue avec la valeur renvoyée par la fonction asynchrone ou qui sera rompue s'il y a une exception non interceptée émise depuis la fonction asynchrone.

+## Description -

Description

+Une fonction `async` peut contenir une expression {{jsxref("Opérateurs/await", "await")}} qui interrompt l'exécution de la fonction asynchrone et attend la résolution de la promesse passée `Promise`. La fonction asynchrone reprend ensuite puis renvoie la valeur de résolution. -

Une fonction async peut contenir une expression {{jsxref("Opérateurs/await", "await")}} qui interrompt l'exécution de la fonction asynchrone et attend la résolution de la promesse passée Promise. La fonction asynchrone reprend ensuite puis renvoie la valeur de résolution.
-
- 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 {{jsxref("SyntaxError")}}.

+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 {{jsxref("SyntaxError")}}. -
-

Note : Lorsqu'une fonction aysnchrone est mise en pause, la fonction appelante continue son exécution (car elle a reçu la promesse implicite renvoyée par la fonction async).

-
+> **Note :** Lorsqu'une fonction aysnchrone est mise en pause, la fonction appelante continue son exécution (car elle a reçu la promesse implicite renvoyée par la fonction `async`). -
-

Note : Le but des fonctions async/await est de simplifier l'utilisation synchrone des promesses et d'opérer sur des groupes de promesses. De la même façon que les promesses sont semblables à des callbacks structurés, async/await est semblable à la combinaison des générateurs et des promesses.

-
+> **Note :** Le but des fonctions `async`/`await` est de simplifier l'utilisation synchrone des promesses et d'opérer sur des groupes de promesses. De la même façon que les promesses sont semblables à des _callbacks_ structurés, `async`/`await` est semblable à la combinaison des générateurs et des promesses. -

Exemples

+## Exemples -

Exemple simple

+### Exemple simple -
var resolveAfter2Seconds = function() {
+```js
+var resolveAfter2Seconds = function() {
   console.log("Initialisation de la promesse lente");
-  return new Promise(resolve => {
+  return new Promise(resolve => {
     setTimeout(function() {
       resolve("lente");
       console.log("La promesse lente est terminée");
@@ -72,7 +64,7 @@ original_slug: Web/JavaScript/Reference/Instructions/async_function
 
 var resolveAfter1Second = function() {
   console.log("Initialisation de la promesse rapide");
-  return new Promise(resolve => {
+  return new Promise(resolve => {
     setTimeout(function() {
       resolve("rapide");
       console.log("La promesse rapide est terminée");
@@ -104,7 +96,7 @@ var concurrentStart = async function() {
 
 var concurrentPromise = function() {
   console.log('==Début concurrentiel avec Promise.all==');
-  return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => {
+  return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => {
     console.log(messages[0]); // lente
     console.log(messages[1]); // rapide
   });
@@ -115,8 +107,8 @@ var parallel = async function() {
 
   // Démarre 2 tâches en parallèle et on attend que les deux soient finies
   await Promise.all([
-      (async()=>console.log(await resolveAfter2Seconds()))(),
-      (async()=>console.log(await resolveAfter1Second()))()
+      (async()=>console.log(await resolveAfter2Seconds()))(),
+      (async()=>console.log(await resolveAfter1Second()))()
   ]);
 }
 
@@ -124,8 +116,8 @@ var parallel = async function() {
 // voir les avertissement ci-après !
 var parallelPromise = function() {
   console.log('==Exécution parallèle avec Promise.then==');
-  resolveAfter2Seconds().then((message)=>console.log(message));
-  resolveAfter1Second().then((message)=>console.log(message));
+  resolveAfter2Seconds().then((message)=>console.log(message));
+  resolveAfter1Second().then((message)=>console.log(message));
 }
 
 sequentialStart(); // après 2 secondes, "lente" est affichée, après une
@@ -144,46 +136,48 @@ setTimeout(parallel, 10000); // réellement parallele : après 1 seconde,
 
 // on attend à nouveau
 setTimeout(parallelPromise, 13000); // identique à parallel
-
+``` -

await et l'exécution parallèle

+#### `await` et l'exécution parallèle -

Dans sequentialStart, l'exécution est arrêtée pendant deux secondes avant le premier await puis encore une autre seconde avant le deuxième await. Le deuxième minuteur n'est pas créé tant que le premier n'est pas écoulé. Le code s'exécute donc au moins en 3 secondes.

+Dans `sequentialStart`, l'exécution est arrêtée pendant deux secondes avant le premier `await` puis encore une autre seconde avant le deuxième `await`. Le deuxième minuteur n'est pas créé tant que le premier n'est pas écoulé. Le code s'exécute donc au moins en 3 secondes. -

Avec concurrentStart, les deux minuteurs sont créés puis attendus derrière un await Les minuteurs sont exécutés de façon concurrente. L'ensemble du code se termine donc en au moins 2 secondes plutôt qu'en 3 secondes.
- Toutefois, les appels utilisant  await sont exécutés séquentiellement et la deuxième instruction avec await attendra que la première ait été  traitée. Le minuteur le plus rapide est donc créé juste après le premier.

+Avec `concurrentStart`, les deux minuteurs sont créés puis attendus derrière un `await` Les minuteurs sont exécutés de façon concurrente. L'ensemble du code se termine donc en au moins 2 secondes plutôt qu'en 3 secondes. +Toutefois, les appels utilisant  `await` sont exécutés séquentiellement et la deuxième instruction avec `await` attendra que la première ait été  traitée. Le minuteur le plus rapide est donc créé juste après le premier. -

Si on souhaite avoir deux tâches qui s'exécutent réellement en parallèle, on pourra utiliser  await Promise.all([job1(), job2()]) comme illustré ci-avant avec parallel.

+Si on souhaite avoir deux tâches qui s'exécutent réellement en parallèle, on pourra utiliser  `await Promise.all([job1(), job2()])` comme illustré ci-avant avec `parallel`. -

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

+#### `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 prêtent mieux à la gestion des erreurs.

+La plupart des fonctions asynchrones peuvent être écrites avec des promesses. Toutefois, les fonctions asynchrones qui utilisent `async` se prêtent mieux à la gestion des erreurs. -

concurrentStart et concurrentPromise sont fonctionnellement équivalentes.
- Avec concurrentStart, si l'un des deux appels échoue, l'exception sera immédiatement interceptée et l'exécution de la fonction asynchrone sera interrompue. L'erreur sera propagée à la fonction appelante via la valeur de retour qui est une promesse implicite.
- Pour obtenir les mêmes sécurités avec les promesses, il faut s'assurer que la fonction renvoie une promesse qui gère ce cas d'échec. Pour concurrentPromise cela signifie qu'il faut renvoyer la promesse de Promise.all([]).then().

+`concurrentStart` et `concurrentPromise` sont fonctionnellement équivalentes. +Avec `concurrentStart`, si l'un des deux appels échoue, l'exception sera immédiatement interceptée et l'exécution de la fonction asynchrone sera interrompue. L'erreur sera propagée à la fonction appelante via la valeur de retour qui est une promesse implicite. +Pour obtenir les mêmes sécurités avec les promesses, il faut s'assurer que la fonction renvoie une promesse qui gère 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 considère la fonction parallel ci-avant, s'il n'y avait eu aucun await ou return pour le résultat de Promise.all([]), aucune erreur n'aurait été propagée.
- Bien que l'exemple parallelPromise paraisse simple, il ne gère aucune erreur du tout. Il aurait fallu utiliser un return Promise.all([]) analogue.

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

Réécrire une chaîne de promesses avec une fonction asynchrone

+### Réécrire une chaîne de promesses avec une fonction asynchrone -

Lorsqu'on utilise une API qui renvoie des promesses ({{jsxref("Promise")}}), on construit une chaîne de promesses et on divise la fonction en de nombreuses branches :

+Lorsqu'on utilise une API qui renvoie des promesses ({{jsxref("Promise")}}), on construit une chaîne de promesses et on divise la fonction en de nombreuses branches : -
function getProcessedData(url) {
+```js
+function getProcessedData(url) {
   return downloadData(url) // renvoie une promesse
-    .catch(e => {
+    .catch(e => {
       return downloadFallbackData(url);  // renvoie une promesse
     })
-    .then(v => {
+    .then(v => {
       return processDataInWorker(v); // renvoie une promesse
     });
 }
-
+``` -

Cela peut être réécrit avec une seule fonction asynchrone, de la façon suivante :

+Cela peut être réécrit avec une seule fonction asynchrone, de la façon suivante : -
async function getProcessedData(url) {
+```js
+async function getProcessedData(url) {
   let v;
   try {
     v = await downloadData(url);
@@ -192,17 +186,18 @@ setTimeout(parallelPromise, 13000); // identique à parallel
   }
   return processDataInWorker(v);
 }
-
+``` -

On voit dans l'exemple précédent qu'il n'y a pas de await pour l'instruction return car la valeur de retour d'une fonction asynchrone est implicitement enveloppée dans un appel à {{jsxref("Promise.resolve")}}.

+On voit dans l'exemple précédent qu'il n'y a pas de `await` pour l'instruction `return` car la valeur de retour d'une fonction asynchrone est implicitement enveloppée dans un appel à {{jsxref("Promise.resolve")}}. -

Différences entre return et return await

+### Différences entre `return` et `return await` -

La conversion automatique des valeurs en promesses avec {{jsxref("Promise.resolve")}} ne signifie pas que return await valeurPromesse sera équivalent à return valeurPromesse.

+La conversion automatique des valeurs en promesses avec {{jsxref("Promise.resolve")}} ne signifie pas que `return await valeurPromesse` sera équivalent à `return valeurPromesse`. -

Si on reprend l'exemple précédent et qu'on le réécrit avec return await et qu'on intercepte une éventuelle erreur de la promesse :

+Si on reprend l'exemple précédent et qu'on le réécrit avec `return await` et qu'on intercepte une éventuelle erreur de la promesse : -
async function getProcessedData(url) {
+```js
+async function getProcessedData(url) {
   let v;
   try {
      v = await downloadData(url);
@@ -214,45 +209,27 @@ setTimeout(parallelPromise, 13000); // identique à parallel
   } catch(e) {
     return null;
   }
-}
- -

Si on avait simplement écrit return processDataInWorker(v);, la promesse renvoyée par la fonction aurait déclenché une exception plutôt que d'être résolue avec la valeur null.

- -

Lorsqu'on utilise return toto;, la valeur toto sera immédiatement renvoyée (sans lever d'exception, quel que soit le cas), tandis que return await toto; attendra la résolution de toto ou son échec et lèvera une exception si besoin avant de parvenir à renvoyer une valeur.

- -

Spécifications

- - - - - - - - - - - - - - - - - - - - - -
SpécificationÉtatCommentaires
{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}{{Spec2('ESDraft')}}
{{SpecName('ES8', '#sec-async-function-definitions', 'async function')}}{{Spec2('ES8')}}Définition initiale.
- -

Compatibilité des navigateurs

- -

{{Compat("javascript.statements.async_function")}}

- -

Voir aussi

- - +} +``` + +Si on avait simplement écrit `return processDataInWorker(v);`, la promesse renvoyée par la fonction aurait déclenché une exception plutôt que d'être résolue avec la valeur `null`. + +Lorsqu'on utilise `return toto;`, la valeur `toto` sera immédiatement renvoyée (sans lever d'exception, quel que soit le cas), tandis que `return await toto;` attendra la résolution de `toto` ou son échec et lèvera une exception si besoin **avant de parvenir à renvoyer une valeur**. + +## Spécifications + +| Spécification | État | Commentaires | +| ---------------------------------------------------------------------------------------------------- | ---------------------------- | -------------------- | +| {{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}} | {{Spec2('ESDraft')}} | | +| {{SpecName('ES8', '#sec-async-function-definitions', 'async function')}} | {{Spec2('ES8')}} | Définition initiale. | + +## Compatibilité des navigateurs + +{{Compat("javascript.statements.async_function")}} + +## Voir aussi + +- {{jsxref("Operators/async_function", "async function expression")}} +- {{jsxref("AsyncFunction")}} object +- {{jsxref("Operators/await", "await")}} +- [Créer des décorateurs asynchrones en JavaScript (billet en anglais sur innolitics.com)](http://innolitics.com/10x/javascript-decorators-for-promise-returning-functions/) -- cgit v1.2.3-54-g00ecf