diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 87d6d2580..a2b305d8d 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -1,10 +1,10 @@ -# Iterables +# Itérables -Les objets *Iterable* sont une généralisation des tableaux. C'est un concept qui permet de rendre n'importe quel objet utilisable dans une boucle `for..of`. +Les objets *itérables* sont une généralisation des tableaux. C'est un concept qui permet de rendre n'importe quel objet utilisable dans une boucle `for..of`. Bien sûr, les tableaux sont itérables. Mais il existe de nombreux autres objets intégrés, qui sont également itérables. Par exemple, les chaînes de caractères sont également itérables. -Si un objet n'est pas techniquement un tableau, mais représente une collection (liste, set) de quelque chose, alors `for..of` est une excellente syntaxe pour boucler dessus, voyons comment le faire fonctionner. +Si un objet n'est pas techniquement un tableau, mais représente une collection (liste, ensemble) de quelque chose, alors `for..of` est une excellente syntaxe pour boucler dessus, voyons comment le faire fonctionner. ## Symbol.iterator @@ -24,9 +24,9 @@ let range = { // for (let num of range) ... num=1,2,3,4,5 ``` -Pour rendre la `range` itérable (et donc laisser `for..of` faire son travail), nous devons ajouter une méthode à l'objet nommé `Symbol.iterator` (un symbole intégré spécial que pour cela). +Pour rendre `range` itérable (et donc laisser `for..of` faire son travail), nous devons ajouter une méthode à l'objet nommé `Symbol.iterator` (un symbole intégré spécial que pour cela). -1. Lorsque `for..of` démarre, il appelle cette méthode une fois (ou des erreurs si il n'est pas trouvé). La méthode doit retourner un *iterator* -- un objet avec la méthode `next`. +1. Lorsque `for..of` démarre, il appelle cette méthode une fois (ou des erreurs s'il n'est pas trouvé). La méthode doit retourner un *itérateur* -- un objet avec la méthode `next`. 2. À partir de là, `for..of` ne fonctionne *qu'avec cet objet retourné*. 3. Quand `for..of` veut la valeur suivante, il appelle `next()` sur cet objet. 4. Le résultat de `next()` doit avoir la forme `{done: Boolean, value: any}`, où `done = true` signifie que l'itération est terminée, sinon `value` doit être la nouvelle valeur. @@ -66,10 +66,10 @@ for (let num of range) { } ``` -Veuillez noter la fonctionnalité principale des iterables : separation of concerns (séparation des préoccupations). +Veuillez noter la fonctionnalité principale des itérables : la séparation des préoccupations (*separation of concerns* en anglais). - Le `range` lui-même n'a pas la méthode `next()`. -- Au lieu de cela, un autre objet, appelé "iterator", est créé par l'appel à `range[Symbol.iterator]()`, et sa méthode `next()` génère des valeurs pour l'itération. +- Au lieu de cela, un autre objet, appelé "itérateur", est créé par l'appel à `range[Symbol.iterator]()`, et sa méthode `next()` génère des valeurs pour l'itération. Ainsi, l'objet itérateur est séparé de l'objet sur lequel il est itéré. @@ -101,9 +101,9 @@ for (let num of range) { } ``` -Maintenant, `range[Symbol.iterator]()` renvoie l'objet `range` lui-même : il dispose de la méthode `next()` et se souvient de la progression de l'itération en cours dans `this.current`. C'est plus court? Oui. Et parfois c'est aussi bien. +Maintenant, `range[Symbol.iterator]()` renvoie l'objet `range` lui-même : il dispose de la méthode `next()` et se souvient de la progression de l'itération en cours dans `this.current`. C'est plus court ? Oui. Et parfois, c'est aussi bien. -L'inconvénient est qu'il est maintenant impossible d'avoir deux boucles `for..of` s'exécutant simultanément sur l'objet: elles partageront l'état d'itération, car il n'y a qu'un seul itérateur -- l'objet lui-même. Cependant, il est rare de disposer de deux for-of parallèles, faisables avec certains scénarios asynchrones. +L'inconvénient est qu'il est maintenant impossible d'avoir deux boucles `for..of` s'exécutant simultanément sur l'objet : elles partageront l'état d'itération, car il n'y a qu'un seul itérateur -- l'objet lui-même. Cependant, il est rare de disposer de deux `for..of` parallèles, faisables avec certains scénarios asynchrones. ```smart header="Itérateurs infinis" Des itérateurs infinis sont également possibles. Par exemple, `range` devient infini pour `range.to = Infinity`. Ou nous pouvons créer un objet itérable qui génère une suite infinie de nombres pseudo-aléatoires. Il peut être aussi utile. @@ -113,9 +113,9 @@ Il n'y a pas de limitation sur `next`, il peut renvoyer de plus en plus de valeu Bien sûr, la boucle `for..of` sur une telle itération serait sans fin. Mais on peut toujours l'arrêter en utilisant `break`. ``` -## String est iterable +## String est itérable -Les tableaux et les chaînes de caractères sont les iterables intégrés les plus largement utilisés. +Les tableaux et les chaînes de caractères sont les itérables intégrés les plus largement utilisés. Pour une chaîne de caractères, `for..of` boucle sur ses caractères : @@ -160,20 +160,20 @@ while (true) { Cela est rarement nécessaire, mais nous donne plus de contrôle sur le processus que `for..of`. Par exemple, nous pouvons scinder le processus d'itération : itérer un peu, puis arrêter, faire autre chose, puis reprendre plus tard. -## Iterables et array-likes [#array-like] +## Itérables et array-likes [#array-like] Il existe deux termes officiels qui se ressemblent mais qui sont très différents. Assurez-vous de bien les comprendre pour éviter la confusion. -- *Iterables* sont des objets qui implémentent la méthode `Symbol.iterator`, comme décrit ci-dessus. +- *Itérables* sont des objets qui implémentent la méthode `Symbol.iterator`, comme décrit ci-dessus. - *Array-likes* sont des objets qui ont des index et des `length`, ils ressemblent donc à des tableaux. -Lorsque nous utilisons JavaScript pour des tâches pratiques dans un navigateur ou d'autres environnements, il est possible que nous rencontrions des objets qui sont iterables ou des array-like, ou les deux. +Lorsque nous utilisons JavaScript pour des tâches pratiques dans un navigateur ou d'autres environnements, il est possible que nous rencontrions des objets qui sont itérables ou des array-like, ou les deux. -Par exemple, les chaînes de caractères sont à la fois iterables (`for..of` fonctionne dessus) et des array-likes (elles ont des index numériques et une longueur). +Par exemple, les chaînes de caractères sont à la fois itérables (`for..of` fonctionne dessus) et des array-likes (elles ont des index numériques et une longueur). Mais un itérable peut ne pas ressembler à un array-like. Et inversement, un array-like peut ne pas être itérable. -Par exemple, la `range` dans l'exemple ci-dessus est itérable, mais pas comme un array-like, car elle n'a pas de propriétés indexées et de `length`. +Par exemple, `range` dans l'exemple ci-dessus est itérable, mais pas comme un array-like, car elle n'a pas de propriétés indexées et de `length`. Et voici l'objet qui ressemble à un tableau, mais pas itérable : @@ -190,7 +190,7 @@ for (let item of arrayLike) {} */!* ``` -Les iterables et les array-likes ne sont généralement *pas des tableaux*, ils n'ont pas `push`, `pop`, etc. C'est plutôt gênant si nous avons un tel objet et que nous voulons travailler avec lui comme avec un tableau. Par exemple, nous aimerions travailler avec une plage en utilisant les méthodes de tableau. Comment y parvenir ? +Les itérables et les array-likes ne sont généralement *pas des tableaux*, ils n'ont pas `push`, `pop`, etc. C'est plutôt gênant si nous avons un tel objet et que nous voulons travailler avec lui comme avec un tableau. Par exemple, nous aimerions travailler avec une plage en utilisant les méthodes de tableau. Comment y parvenir ? ## Array.from @@ -287,17 +287,17 @@ alert( str.slice(1, 3) ); // ordures (deux pièces de paires de substitution dif ## Résumé -Les objets pouvant être utilisés dans `for..of` s'appellent *iterable*. +Les objets pouvant être utilisés dans `for..of` s'appellent *itérables*. -- Techniquement, les iterables doivent implémenter la méthode nommée `Symbol.iterator`. +- Techniquement, les itérables doivent implémenter la méthode nommée `Symbol.iterator`. - Le résultat de `obj[Symbol.iterator]()` s'appelle un *itérateur*. Il gère le processus d'itération ultérieur. - Un itérateur doit avoir la méthode nommée `next()` qui retourne un objet `{done: Boolean, value: any}`, ici `done: true` dénote la fin du processus de l'itération, sinon `value` est la valeur suivante. - La méthode `Symbol.iterator` est appelée automatiquement par `for..of`, mais nous pouvons aussi le faire directement. -- Les iterables intégrés tels que des chaînes de caractères ou des tableaux implémentent également `Symbol.iterator`. +- Les itérables intégrés tels que des chaînes de caractères ou des tableaux implémentent également `Symbol.iterator`. - L'itérateur de chaîne de caractères connaît les paires de substitution. Les objets qui ont des propriétés indexées et des `length` sont appelés *array-like*. De tels objets peuvent également avoir d'autres propriétés et méthodes, mais ne possèdent pas les méthodes intégrées des tableaux. -Si nous regardons à l'intérieur de la spécification -- nous verrons que la plupart des méthodes intégrées supposent qu'elles fonctionnent avec des éléments iterables ou des array-like au lieu de "vrais" tableaux, car c'est plus abstrait. +Si nous regardons à l'intérieur de la spécification -- nous verrons que la plupart des méthodes intégrées supposent qu'elles fonctionnent avec des éléments itérables ou des array-like au lieu de "vrais" tableaux, car c'est plus abstrait. `Array.from(obj[, mapFn, thisArg])` créer un véritable `Array` à partir d'un `obj` itérable ou array-like, et nous pouvons ensuite utiliser des méthodes de tableau sur celui-ci. Les arguments optionnels `mapFn` et `thisArg` nous permettent d'appliquer une fonction à chaque élément. diff --git a/1-js/11-async/03-promise-chaining/article.md b/1-js/11-async/03-promise-chaining/article.md index d5fee64a1..50cbd514e 100644 --- a/1-js/11-async/03-promise-chaining/article.md +++ b/1-js/11-async/03-promise-chaining/article.md @@ -41,7 +41,7 @@ Ici, le flux est : 3. Le `then` suivant `(***)` obtient le résultat du précédent, le traite (double) et le passe au gestionnaire suivant. 4. ...et ainsi de suite. -Lorsque le résultat est transmis le long de la chaîne de gestionnaires, nous pouvons voir une séquence d'appels `alert`: `1` -> `2` -> `4`. +Lorsque le résultat est transmis le long de la chaîne de gestionnaires, nous pouvons voir une séquence d'appels `alert` : `1` -> `2` -> `4`. ![](promise-then-chain.svg) @@ -49,9 +49,9 @@ Le tout fonctionne, parce qu’un appel à `.then` renvoie une nouvelle promesse Lorsqu'un gestionnaire renvoie une valeur, cela devient le résultat de cette promesse. Le prochain `.then` est appelé avec. -**Une erreur classique pour les débutants: techniquement, nous pouvons également ajouter plusieurs `.then` à une seule promesse. Ceci n'est pas le chaînage des promesses.** +**Une erreur classique pour les débutants : techniquement, nous pouvons également ajouter plusieurs `.then` à une seule promesse. Ceci n'est pas le chaînage des promesses.** -Par example : +Par exemple : ```js run let promise = new Promise(function(resolve, reject) { @@ -76,7 +76,7 @@ promise.then(function(result) { Ce que nous avons fait ici n’est qu'ajouter plusieurs gestionnaires pour une promesse. Ils ne se transmettent pas le résultat, ils la traitent de manière indépendante. -Voici la representation (comparez-la avec l'enchaînement ci-dessus): +Voici la représentation (comparez-la avec l'enchaînement ci-dessus) : ![](promise-then-many.svg) @@ -84,13 +84,13 @@ Tous les `.then` sur la même promesse obtiennent le même résultat - le résul En pratique, nous avons rarement besoin de plusieurs gestionnaires pour une même promesse. Le chaînage est utilisé beaucoup plus souvent. -## Renvoie de promesses +## Renvoi de promesses Un gestionnaire, utilisé dans `.then(handler)` peut créer et renvoyer une promesse. Dans ce cas, les autres gestionnaires attendent que le problème soit réglé, puis le résultat est obtenu. -Par exemple: +Par exemple : ```js run new Promise(function(resolve, reject) { @@ -122,15 +122,15 @@ new Promise(function(resolve, reject) { }); ``` -Ici, le premier `.then` affiche `1` et renvoie `new Promise(…)` à la ligne `(*)`. Au bout d'une seconde c'est résolu et le résultat (l'argument de `resolve`, ici, `result * 2`) est transmis au gestionnaire du deuxième `.then`. Ce gestionnaire est à la ligne `(**)`, il affiche `2` et fait la même chose. +Ici, le premier `.then` affiche `1` et renvoie `new Promise(…)` à la ligne `(*)`. C'est résolu au bout d'une seconde et le résultat (l'argument de `resolve`, ici, `result * 2`) est transmis au gestionnaire du deuxième `.then`. Ce gestionnaire est à la ligne `(**)`, il affiche `2` et fait la même chose. -Le résultat est donc le même que dans l'exemple précédent: 1 -> 2 -> 4, mais maintenant avec un délai d'une seconde entre les appels `alert`. +Le résultat est donc le même que dans l'exemple précédent : 1 -> 2 -> 4, mais maintenant avec un délai d'une seconde entre les appels `alert`. -Le renvoie des promesses nous permet de construire des chaînes d’actions asynchrones. +Le renvoi des promesses nous permet de construire des chaînes d’actions asynchrones. -## Exemple: loadScript +## Exemple : loadScript -Utilisons cette fonctionnalité avec le `loadScript` promisifié, défini dans le [chapitre précédent](info:promise-basics#loadscript), afin de charger les scripts un à un, dans l'ordre: +Utilisons cette fonctionnalité avec le `loadScript` promisifié, défini dans le [chapitre précédent](info:promise-basics#loadscript), afin de charger les scripts un à un, dans l'ordre : ```js run loadScript("/article/promise-chaining/one.js") @@ -149,7 +149,7 @@ loadScript("/article/promise-chaining/one.js") }); ``` -Ce code peut être un peu plus court avec les fonctions fléchées: +Ce code peut être un peu plus court avec les fonctions fléchées : ```js run loadScript("/article/promise-chaining/one.js") @@ -166,9 +166,9 @@ loadScript("/article/promise-chaining/one.js") Ici, chaque appel à `loadScript` renvoie une promesse et le prochain `.then` s'exécute lorsqu'il est résolu. Ensuite, il lance le chargement du script suivant. Les scripts sont donc chargés les uns après les autres. -Nous pouvons ajouter plus d'actions asynchrones à la chaîne. Noter que le code est toujours "plat", il grandit verticallement, pas vers la droite. Il n'y a aucun signe de "pyramid of doom". +Nous pouvons ajouter plus d'actions asynchrones à la chaîne. Noter que le code est toujours "plat", il grandit verticalement, pas vers la droite. Il n'y a aucun signe de "pyramid of doom". -Techniquement, nous pourrions ajouter `.then` directement à chaque `loadScript`, comme ceci: +Techniquement, nous pourrions ajouter `.then` directement à chaque `loadScript`, comme ceci : ```js run loadScript("/article/promise-chaining/one.js").then(script1 => { @@ -183,7 +183,7 @@ loadScript("/article/promise-chaining/one.js").then(script1 => { }); ``` -Ce code fait la même chose: charge 3 scripts en séquence. Mais il "pousse vers la droite". Nous avons donc le même problème qu'avec les callbacks. +Ce code fait la même chose : charge 3 scripts en séquence. Mais il "pousse vers la droite". Nous avons donc le même problème qu'avec les callbacks. Les gens qui commencent à utiliser leurs promesses ne savent parfois pas comment enchaîner, alors ils l'écrivent de cette façon. Généralement, le chaînage est préféré. @@ -191,7 +191,7 @@ Parfois, il est correct d'écrire directement `.then`, car la fonction imbriqué ````smart header="Thenables" -Pour être précis, un gestionnaire peut renvoyer pas exactement une promesse, mais un soi-disant objet "thenable" - un objet arbitraire doté de la méthode `.then`. Il sera traité de la même manière q'une promesse. +Pour être précis, un gestionnaire peut renvoyer pas exactement une promesse, mais un soi-disant objet "thenable" - un objet arbitraire doté de la méthode `.then`. Il sera traité de la même manière qu'une promesse. L'idée est que les bibliothèques tierces peuvent implémenter leurs propres objets "compatibles avec les promesses". Elles peuvent avoir un ensemble étendu de méthodes, mais aussi être compatibles avec les promesses natives, car ils implémentent `.then`. @@ -224,21 +224,21 @@ Cette fonctionnalité nous permet d'intégrer des objets personnalisés avec des ```` -## Un plus grand exemple: fetch +## Un plus grand exemple : fetch Dans la programmation du front-end, les promesses sont souvent utilisées pour les requêtes réseau. Voyons donc un exemple étendu de cela. -Nous allons utiliser la méthode [fetch](info:fetch) pour charger les informations sur l'utilisateur à partir du serveur distant. Il a beaucoup de paramètres optionnels couverts dans [des chapitres séparés](info:fetch), mais la syntaxe de base est assez simple: +Nous allons utiliser la méthode [fetch](info:fetch) pour charger les informations sur l'utilisateur à partir du serveur distant. Il a beaucoup de paramètres optionnels couverts dans [des chapitres séparés](info:fetch), mais la syntaxe de base est assez simple : ```js let promise = fetch(url); ``` -Cela fait une requête réseau à la `url` et renvoie une promesse. La promesse se résout avec un objet `response` lorsque le serveur distant répond avec des en-têtes, mais *avant le téléchargement complet de la réponse*. +Cela fait une requête réseau à `url` et renvoie une promesse. La promesse se résout avec un objet `response` lorsque le serveur distant répond avec des en-têtes, mais *avant le téléchargement complet de la réponse*. Pour lire la réponse complète, nous devons appeler la méthode `response.text()` : elle renvoie une promesse qui résout le téléchargement du texte intégral à partir du serveur distant, avec ce texte en tant que résultat. -Le code ci-dessous envoie une requête à `user.json` et charge son texte depuis le serveur: +Le code ci-dessous envoie une requête à `user.json` et charge son texte depuis le serveur : ```js run fetch('/article/promise-chaining/user.json') @@ -256,7 +256,7 @@ fetch('/article/promise-chaining/user.json') L'objet `response` renvoyé par `fetch` comprend également la méthode `response.json()` qui lit les données distantes et les analyse en JSON. Dans notre cas, c'est encore plus pratique, alors passons-y. -Nous allons également utiliser les fonctions fléchées pour la brièveté: +Nous allons également utiliser les fonctions fléchées pour la brièveté : ```js run // comme ci-dessus, mais response.json() analyse le contenu distant en tant que JSON @@ -267,7 +267,7 @@ fetch('/article/promise-chaining/user.json') Maintenant faisons quelque chose avec l'utilisateur chargé. -Par exemple, nous pouvons faire une demande supplémentaire à GitHub, charger le profil de l'utilisateur et afficher l'avatar: +Par exemple, nous pouvons faire une demande supplémentaire à GitHub, charger le profil de l'utilisateur et afficher l'avatar : ```js run // Faire une demande pour user.json @@ -291,11 +291,11 @@ fetch('/article/promise-chaining/user.json') Le code fonctionne ; voir les commentaires à propos des détails. Pourtant, il y a un problème potentiel, une erreur typique de ceux qui commencent à utiliser les promesses. -Regardez la ligne `(*)`: comment pouvons-nous faire quelque chose *après* l'avatar a fini d'afficher et d'être supprimé? Par exemple, nous aimerions montrer un formulaire pour éditer cet utilisateur ou autre chose. Pour l'instant, il n'y a pas moyen. +Regardez la ligne `(*)`: comment pouvons-nous faire quelque chose *après* que l'avatar a fini d'afficher et d'être supprimé ? Par exemple, nous aimerions pouvoir afficher un formulaire permettant d'éditer cet utilisateur ou autre chose. Pour l'instant, il n'y a pas moyen d'y parvenir. Pour rendre la chaîne extensible, nous devons retourner une promesse qui sera résolue une fois que l'avatar aura fini de s'afficher. -Comme ceci: +Comme ceci : ```js run fetch('/article/promise-chaining/user.json') @@ -325,7 +325,7 @@ En d’autres termes, le gestionnaire `.then` à la ligne `(*)` renvoie `new Pro Comme bonne pratique, une action asynchrone doit toujours renvoyer une promesse. Cela permet de planifier des actions après. Même si nous n'avons pas l'intention d'étendre la chaîne maintenant, nous en aurons peut-être besoin plus tard. -Enfin, nous pouvons scinder le code en fonctions réutilisables: +Enfin, nous pouvons scinder le code en fonctions réutilisables : ```js run function loadJson(url) { @@ -363,6 +363,6 @@ loadJson('/article/promise-chaining/user.json') Si un gestionnaire `.then` (ou `catch/finally`, peu importe) renvoie une promesse, le reste de la chaîne attend jusqu'à ce qu'elle se règle. Quand cela se produit, son résultat (ou son erreur) est passé plus loin. -Voici une image complète: +Voici une image complète : ![](promise-handler-variants.svg) diff --git a/1-js/11-async/04-promise-error-handling/article.md b/1-js/11-async/04-promise-error-handling/article.md index bd9d5ef8d..cdec49980 100644 --- a/1-js/11-async/04-promise-error-handling/article.md +++ b/1-js/11-async/04-promise-error-handling/article.md @@ -44,7 +44,7 @@ Normalement, un tel `.catch` ne se déclenche pas du tout. Mais si l'une des pro Le code d'un exécuteur de promesses et d'un gestionnaire de promesses est entouré d'un "`try...catch` invisible". Si une exception se produit, elle est prise en compte et traitée comme un rejet. -Par exemple, ce code: +Par exemple, ce code : ```js run new Promise((resolve, reject) => { @@ -54,7 +54,7 @@ new Promise((resolve, reject) => { }).catch(alert); // Error: Whoops! ``` -...Fonctionne exactement de la même façon que ceci: +...Fonctionne exactement de la même façon que ceci : ```js run new Promise((resolve, reject) => { @@ -68,7 +68,7 @@ Le "`try..catch` invisible" autour de l'exécuteur attrape automatiquement l'err Cela se produit non seulement dans la fonction exécuteur, mais aussi dans ses gestionnaires. Si nous utilisons `throw` à l'intérieur d'un gestionnaire `.then', cela signifie une promesse rejetée, donc le contrôle saute au gestionnaire d'erreur le plus proche. -En voici un exemple: +En voici un exemple : ```js run new Promise((resolve, reject) => { @@ -98,11 +98,11 @@ Le `.catch` final n'attrape pas seulement les rejets explicites, mais aussi les Comme nous l'avons déjà remarqué, `.catch` à la fin de la chaîne est similaire à `try...catch`. Nous pouvons avoir autant de gestionnaires `.then` que nous le voulons, puis utiliser un seul `.catch` à la fin pour gérer les erreurs dans chacun d'eux. -Dans un `try...catch` classique nous pouvons analyser l'erreur et peut-être la relancer si nous ne pouvons pas la gérer. La même chose est possible pour les promesses. +Dans un `try...catch` classique, nous pouvons analyser l'erreur et peut-être la relancer si nous ne pouvons pas la gérer. La même chose est possible pour les promesses. Si nous utilisons `throw` dans `.catch`, alors le contrôle passe au gestionnaire d'erreur suivant qui est plus proche. Et si nous gérons l'erreur et finissons normalement, alors elle continue jusqu'au gestionnaire `.then` le plus proche. -In the example below the `.catch` successfully handles the error: +Dans l'exemple ci-dessous, le `.catch` gère l'erreur avec succès : ```js run // l'exécution: catch -> then @@ -119,7 +119,7 @@ new Promise((resolve, reject) => { Ici, le bloc `.catch` se termine normalement. Le prochain gestionnaire `.then` réussi est donc appelé. -Dans l'exemple ci-dessous nous voyons l'autre situation avec `.catch`. Le gestionnaire `(*)` attrape l'erreur et ne peut tout simplement pas la gérer (par ex: il sait seulement comment gérer `URIError`), donc il la relance: +Dans l'exemple ci-dessous, nous voyons l'autre situation avec `.catch`. Le gestionnaire `(*)` attrape l'erreur et ne peut tout simplement pas la gérer (par ex : il sait seulement comment gérer `URIError`), donc il la relance : ```js run // l'exécution: catch -> catch @@ -149,7 +149,7 @@ new Promise((resolve, reject) => { }); ``` -The execution jumps from the first `.catch` `(*)` to the next one `(**)` down the chain. +L'exécution saute du premier `.catch` `(*)` au suivant `(**)` dans la chaîne. ## Rejets non traités @@ -202,4 +202,4 @@ Dans les environnements sans navigateur comme Node.js, il existe d'autres moyens - `.then` intercepte également les erreurs de la même manière, si on lui donne le deuxième argument (qui est le gestionnaire d'erreurs). - Nous devrions placer `.catch` exactement aux endroits où nous voulons traiter les erreurs et savoir comment les traiter. Le gestionnaire doit analyser les erreurs (les classes d'erreurs personnalisées aident) et relancer les erreurs inconnues (ce sont peut-être des erreurs de programmation). - C'est acceptable de ne pas utiliser `.catch` du tout, s'il n'y a aucun moyen de récupérer d'une erreur. -- Dans tous les cas, nous devrions avoir le gestionnaire d'événements `unhandledrejection` (pour les navigateurs, et les analogues pour les autres environnements), pour suivre les erreurs non gérées et informer l'utilisateur (et probablement notre serveur) à leur sujet, afin que notre application ne "meurt jamais". +- Dans tous les cas, nous devrions avoir le gestionnaire d'événements `unhandledrejection` (pour les navigateurs, et les analogues pour les autres environnements), pour suivre les erreurs non gérées et informer l'utilisateur (et probablement notre serveur) à leur sujet, afin que notre application ne "meure jamais". diff --git a/1-js/11-async/05-promise-api/article.md b/1-js/11-async/05-promise-api/article.md index dfc3ae573..3cdff6745 100644 --- a/1-js/11-async/05-promise-api/article.md +++ b/1-js/11-async/05-promise-api/article.md @@ -10,7 +10,7 @@ Par exemple, téléchargez plusieurs URLs en parallèle et traitez le contenu lo C'est à cela que sert `Promise.all`. -La syntaxe est: +La syntaxe est : ```js let promise = Promise.all(iterable); @@ -20,7 +20,7 @@ let promise = Promise.all(iterable); La nouvelle promesse est résolue lorsque toutes les promesses énumérées sont résolues et que le tableau de leurs résultats devient son résultat. -Par exemple, le `Promise.all` ci-dessous se règle après 3 secondes, et ensuite son résultat est un tableau `[1, 2, 3]`: +Par exemple, le `Promise.all` ci-dessous se règle après 3 secondes, et ensuite son résultat est un tableau `[1, 2, 3]` : ```js run Promise.all([ @@ -34,7 +34,7 @@ Veuillez noter que l'ordre des éléments du tableau résultant est le même que Une astuce courante consiste à mapper un tableau de données de tâches dans un tableau de promesses, puis à l'intégrer dans `Promise.all`. -Par exemple, si nous avons un tableau d'URLs, nous pouvons tous les récupérer comme ceci: +Par exemple, si nous avons un tableau d'URLs, nous pouvons tous les récupérer comme ceci : ```js run let urls = [ @@ -77,7 +77,7 @@ Promise.all(requests) **Si l'une des promesses est rejetée, la promesse retournée par `Promise.all` est rejetée immédiatement avec cette erreur.** -Par exemple: +Par exemple : ```js run Promise.all([ @@ -100,9 +100,9 @@ Par exemple, s'il y a plusieurs appels `fetch, comme dans l'exemple ci-dessus, e ``` ````smart header="`Promise.all(iterable)` autorise toutes les valeurs \"régulières\" qui ne sont pas une promesse dans `iterable`" -Normallement, `Promise.all(...)` accepte un itérable (dans la plupart des cas, un tableau) de promesses. Mais si l'un de ces objets n'est pas une promesse, il est transmis au tableau résultant "tel quel". +Normalement, `Promise.all(...)` accepte un itérable (dans la plupart des cas, un tableau) de promesses. Mais si l'un de ces objets n'est pas une promesse, il est transmis au tableau résultant "tel quel". -Par exemple, ici les résultats sont les suivants `[1, 2, 3]`: +Par exemple, ici les résultats sont les suivants `[1, 2, 3]` : ```js run Promise.all([ @@ -136,7 +136,7 @@ Promise.all([ - `{status:"fulfilled", value:result}` pour les réponses réussies, - `{status:"rejected", reason:error}` pour les erreurs. -Par exemple, nous aimerions récupérer l'information sur les utilisateurs multiples. Même si une demande échoue, les autres nous intéressent. +Par exemple, nous aimerions récupérer l'information de multiples utilisateurs. Même si une demande échoue, les autres nous intéressent. Utilisons `Promise.allSettled`: @@ -160,7 +160,7 @@ Promise.allSettled(urls.map(url => fetch(url))) }); ``` -Les `résultats` dans la ligne `(*)` ci-dessus seront: +Les `résultats` dans la ligne `(*)` ci-dessus seront : ```js [ {status: 'fulfilled', value: ...response...}, @@ -173,7 +173,7 @@ Ainsi, pour chaque promesse, nous obtenons son statut et `value/error`. ### Polyfill -Si le navigateur ne prend pas en charge `Promise.allSettled`, il est facile de le polyfill: +Si le navigateur ne prend pas en charge `Promise.allSettled`, il est facile de le polyfill : ```js if (!Promise.allSettled) { @@ -219,15 +219,15 @@ La première promesse a été la plus rapide, donc, elle est devenue le résulta ## Promise.any -Similar to `Promise.race`, but waits only for the first fulfilled promise and gets its result. If all of the given promises are rejected, then the returned promise is rejected with [`AggregateError`](mdn:js/AggregateError) - a special error object that stores all promise errors in its `errors` property. +Similaire à `Promise.race`, mais n'attend que la première promesse accomplie et prend son résultat. Si toutes les promesses données sont rejetées, alors la promesse retournée est rejetée avec [`AggregateError`](mdn:js/AggregateError) - un objet d'erreur spécial qui stocke toutes les erreurs de promesse dans sa propriété `errors`. -The syntax is: +La syntaxe est : ```js let promise = Promise.any(iterable); ``` -For instance, here the result will be `1`: +Par exemple, ici le résultat sera `1` : ```js run Promise.any([ @@ -237,9 +237,9 @@ Promise.any([ ]).then(alert); // 1 ``` -The first promise here was fastest, but it was rejected, so the second promise became the result. After the first fulfilled promise "wins the race", all further results are ignored. +La première promesse était la plus rapide, mais elle a été rejetée, de sorte que la deuxième promesse est devenue le résultat. Une fois que la première promesse accomplie a "gagné la course", tous les autres résultats sont ignorés. -Here's an example when all promises fail: +Voici un exemple dans lequel toutes les promesses échouent : ```js run Promise.any([ @@ -252,7 +252,7 @@ Promise.any([ }); ``` -As you can see, error objects for failed promises are available in the `errors` property of the `AggregateError` object. +Comme vous pouvez le voir, les objets d'erreur des promesses échouées sont disponibles dans la propriété `errors` de l'objet `AggregateError`. ## Promise.resolve/reject @@ -264,7 +264,7 @@ Nous les couvrons ici par souci de clarté, et pour ceux qui ne peuvent pas util - `Promise.resolve(value)` crée une promesse résolue avec le résultat `value`. -Comme pour: +Comme pour : ```js let promise = new Promise(resolve => resolve(value)); @@ -299,7 +299,7 @@ Nous pouvons écrire `loadCached(url).then(...)`, car la fonction est garantie d - `Promise.reject(error)` crée une promesse rejetée avec `error`. -Comme pour: +Comme pour : ```js let promise = new Promise((resolve, reject) => reject(error)); @@ -309,10 +309,10 @@ En pratique, cette méthode n'est presque jamais utilisée. ## Résumé -Il y a 6 méthodes statiques de la classe `Promise`: +Il y a 6 méthodes statiques de la classe `Promise` : 1. `Promise.all(promises)` -- attend que toutes les promesses se résolvent et retourne un tableau de leurs résultats. Si l'une des promesses données est rejetée, alors elle devient l'erreur de `Promise.all`, et tous les autres résultats sont ignorés. -2. `Promise.allSettled(promises)` (méthode récemment ajoutée) -- attend que toutes les promesses se règlent et retourne leurs résultats sous forme de tableau d'objets avec: +2. `Promise.allSettled(promises)` (méthode récemment ajoutée) -- attend que toutes les promesses se règlent et retourne leurs résultats sous forme de tableau d'objets avec : - `state`: `"fulfilled"` ou `"rejected"` - `value` (si rempli) ou `reason` (en cas de rejet). 3. `Promise.race(promises)` -- attend que la première promesse soit réglée, et son résultat/erreur devient le résultat.