You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/11-async/02-promise-basics/article.md
+32-30Lines changed: 32 additions & 30 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,17 +2,19 @@
2
2
3
3
Imaginez que vous êtes un grand chanteur et les fans vous demandent jour et nuit votre prochaine chanson.
4
4
5
-
Pour avoir un peu de paix, vous promettez de leur envoyer dès que celui-ci est publié. Vous donnez à vos fans une liste d'abonnement. Ils peuvent y ajouter leur adresse mail, comme cela, quand le single est sorti, tous les emails reçoivent votre single. Et même si quelque chose arrive, comme un feu dans le studio, et que vous ne pouvez sortir le single, ils en seront aussi notifiés.
5
+
Pour avoir un peu de paix, vous promettez de leur envoyer dès que celle-ci est publiée. Vous donnez à vos fans une liste d'abonnement. Ils peuvent y ajouter leur adresse mail, comme cela, quand le single est sorti, tous les emails reçoivent votre single. Et même si quelque chose arrive, comme un feu dans le studio, et que vous ne pouvez pas sortir le single, ils en seront aussi notifiés.
6
6
7
7
Tout le monde est content : vous, puisque l'on vous laisse plus tranquille, et vos fans parce qu'ils savent qu'ils ne rateront pas la chanson.
8
8
9
9
C'est une analogie réelle à un problème courant de programmation :
10
10
11
11
1. Un "producteur de code" qui réalise quelque chose mais nécessite du temps. Par exemple, un code qui charge des données à travers un réseau. C'est le "chanteur".
12
12
2. Un "consommateur de code" qui attend un résultat du "producteur de code" quand il est prêt. Beaucoup de fonctions peuvent avoir besoin de ce résultat. Ces fonctions sont les "fans".
13
-
3. Une *promesse* (promise) est un objet spécial en javascript qui lie le "producteur de code" et le "consommateur de code" ensemble. En comparant à notre analogie c'est la "liste d'abonnement". Le "producteur de code" prends le temps nécessaires pour produire le résultat promis, et la "promesse" donne le résultat disponible pour le code abonné quand c'est prêt.
13
+
3. Une *promesse* (promise) est un objet spécial en Javascript qui lie le "producteur de code" et le "consommateur de code" ensemble. En comparant à notre analogie c'est la "liste d'abonnement". Le "producteur de code" prend le temps nécessaire pour produire le résultat promis, et la "promesse" donne le résultat disponible pour le code abonné quand c'est prêt.
14
+
15
+
16
+
L'analogie n'est pas la plus correcte, car les promesses en Javascript sont un peu plus complexes qu'une simple liste d'abonnement : elles ont d'autres possibilités mais aussi certaines limitations. Toutefois c'est suffisant pour débuter.
14
17
15
-
L'analogie n'est pas la plus correcte, car les promesses en Javascript sont un peu plus complexes qu'une simple liste d'abonnement : elles ont d'autres possibilités mais aussi des certaines limitations. Toutefois c'est suffisant pour débuter.
16
18
17
19
La syntaxe du constructeur pour une promesse est :
18
20
@@ -22,29 +24,29 @@ let promise = new Promise(function(resolve, reject) {
22
24
});
23
25
```
24
26
25
-
La fonction passée à `new Promise` est appelée l'*exécuteur*. Quand `new Promise` est créée, elle est lancée automatiquement. Elle contient le producteur de code, qui doit produire un résulat final. Dans l'analogie au-dessus : l'éxécuteur est le "chanteur".
27
+
La fonction passée à `new Promise` est appelée l'*exécuteur*. Quand `new Promise` est créée, elle est lancée automatiquement. Elle contient le producteur de code, qui doit produire un résulat final. Dans l'analogie ci-dessus : l'exécuteur est le "chanteur".
26
28
27
-
Ses arguments `resolve` (tenir) et `reject` (rompre) sont les fonctions de retours directement fournies par Javascript. Notre code est inclus seulement dans l'exécuteur.
29
+
Ses arguments `resolve` (tenir) et `reject` (rompre) sont les fonctions de retour directement fournies par Javascript. Notre code est inclus seulement dans l'exécuteur.
28
30
29
-
Quand l'exécuteur obtient un résultat, qu'il soit rapide ou pas, cela n'a pas d'importance, il appellera une des deux fonctions callbacks :
31
+
Quand l'exécuteur obtient un résultat, qu'il soit rapide ou pas, cela n'a pas d'importance, il appellera une des deux fonctions de retour :
30
32
31
-
-`resolve(value)` - si la tâche s'est terminée avec succés, avec le résultat `value`.
33
+
-`resolve(value)` - si la tâche s'est terminée avec succès, avec le résultat `value`.
32
34
-`reject(error)` - si une erreur est survenue, `error` est l'objet erreur.
33
35
34
36
Donc, pour résumer : l'exécuteur s'exécute automatiquement et tente d’effectuer un travail. Ensuite, il devrait appeler `resolve` s'il a réussi ou `reject` s'il y avait une erreur.
35
37
36
38
L'objet `promise` retourné par le constructeur `new Promise` a des propriétés internes :
37
39
38
-
-`state` (état) - initiallement à `"pending"` (en attente), se change soit en `"fulfilled"` (tenue) lorsque `resolve` est appelé ou `"rejected"` (rompue) si `reject` est appelé.
39
-
-`result` - initialement à `undefined` se change à`value` quand `resolve(value)` est appelé ou `error` quand `reject(error)` est appelé.
40
+
-`state` (état) - initialement à `"pending"` (en attente), se change soit en `"fulfilled"` (tenue) lorsque `resolve` est appelé ou `"rejected"` (rompue) si `reject` est appelé.
41
+
-`result` - initialement à `undefined` se change en`value` quand `resolve(value)` est appelé ou en`error` quand `reject(error)` est appelé.
40
42
41
-
Ainsi l'éxécuteur changera la promesse à un de ces états :
43
+
Ainsi l'exécuteur changera la promesse à un de ces états :
42
44
43
45

44
46
45
47
Plus tard nous verrons comment les "fans" peuvent s'abonner à ces changements.
46
48
47
-
Voici un exemple d'un constructeur d'une promesse et d'une fonction exécutrice simple avec un "code produit" qui prends du temps (utilisant `setTimeout`) :
49
+
Voici un exemple d'un constructeur d'une promesse et d'une fonction exécutrice simple avec un "code produit" qui prend du temps (utilisant `setTimeout`) :
48
50
49
51
```js run
50
52
let promise =newPromise(function(resolve, reject) {
@@ -54,16 +56,16 @@ let promise = new Promise(function(resolve, reject) {
54
56
setTimeout(() =>*!*resolve("done")*/!*, 1000);
55
57
});
56
58
```
57
-
On peut voir deux chose en lançant le code ci-dessus :
59
+
On peut voir deux choses en lançant le code ci-dessus :
58
60
59
61
1. L'exécuteur est appelé automatiquement et immédiatement (avec `new Promise`).
60
-
2. L'exécuteur reçoit deux arguments : `resolve` et `reject` - ces deux fonctions sont pré-définies par le moteur Javascript, ainsi nous n'avons pas besoin de les créer. Nous devons seulement appelé l'une ou l'autre quand le résultat est prêt.
62
+
2. L'exécuteur reçoit deux arguments : `resolve` et `reject` - ces deux fonctions sont pré-définies par le moteur Javascript, ainsi nous n'avons pas besoin de les créer. Nous devons seulement appeler l'une ou l'autre quand le résultat est prêt.
61
63
62
64
Après une seconde de "traitement" l'exécuteur appelle `resolve("done")` pour produire le résultat. Cela change l'état de l'objet `promise` :
63
65
64
66

65
67
66
-
Nous avons vu un exemple d'une tâche terminée avec succés, une promesse "tenue".
68
+
Nous avons vu un exemple d'une tâche terminée avec succès, une promesse "tenue".
67
69
68
70
Voyons maintenant un exemple d'un exécuteur rompant la promesse avec une erreur :
69
71
@@ -78,9 +80,9 @@ L'appel a `reject(...)` change l'object promesse à l'état `"rejected"` :
78
80
79
81

80
82
81
-
Pour résumer, l'exécuteur devrait réaliser une tâche (normalement quelque chose qui prends du temps) puis appelle `resolve` ou `reject` pour changer l'état de l'objet promesse correspondant.
83
+
Pour résumer, l'exécuteur devrait réaliser une tâche (normalement quelque chose qui prend du temps) puis appelle `resolve` ou `reject` pour changer l'état de l'objet promesse correspondant.
82
84
83
-
Une promesse qui est soit tenue ou rejetée est appelée "settled" (acquitttée) opposé à une promesse initialisée à "en attente".
85
+
Une promesse qui est soit tenue soit rejetée est appelée "settled" (acquitttée) par opposition à une promesse initialisée à "en attente".
84
86
85
87
````smart header="Il ne peut y avoir qu'un seul résultat ou une erreur"
86
88
L'exécuteur devrait appeler seulement une fois `resolve` ou `reject`. N'importe quel changement d'état est définitif.
@@ -100,19 +102,19 @@ let promise = new Promise(function(resolve, reject) {
100
102
101
103
L'idée est que la tâche exécutée par un exécuteur ne peut avoir qu'un seul résultat ou une erreur.
102
104
103
-
De plus, `resolve`/`reject` attendent qu'un seul argument (ou aucun) et ignorera les arguments suivants.
105
+
De plus, `resolve`/`reject` n'attend qu'un seul argument (ou aucun) et ignorera les arguments suivants.
104
106
````
105
107
106
108
```smart header="Rompre avec l'objet `Error`"
107
-
Dans le cas ou quelque chose se passe mal, l'exécuteur doit appeler `reject`. Cela est possible avec n'importe type d'argument (comme pour `resolve`). Mais il est plutôt recommandé d'utiliser l'objet `Error` (ou les object en héritant). La raison va vous paraître évident dans un instant.
109
+
Dans le cas ou quelque chose se passe mal, l'exécuteur doit appeler `reject`. Cela est possible avec n'importe type d'argument (comme pour `resolve`). Mais il est plutôt recommandé d'utiliser l'objet `Error` (ou les objets en héritant). La raison va vous paraître évidente dans un instant.
108
110
```
109
111
110
112
````smart header="Appel de `resolve`/`reject` immédiat"
111
113
En pratique, un exécuteur réalise normalement une opération asynchrone et appelle `resolve`/`reject` après un certain temps, mais il n'est pas obligatoire d'être asynchrone. On peut aussi appeler immédiatement `resolve` ou `reject`, comme cela :
112
114
113
115
```js
114
116
let promise = new Promise(function(resolve, reject) {
115
-
// La tâche ne prends pas de temps
117
+
// La tâche ne prend pas de temps
116
118
resolve(123); // rend immédiatement le résultat : 123
117
119
});
118
120
```
@@ -128,7 +130,7 @@ Les propriétés `state` et `result` de l'objet `Promise` sont internes. Nous ne
128
130
129
131
## Les consommateurs : then, catch
130
132
131
-
Un objet promesse permet le lien entre l'exécuteur (le "code produit" ou "chanteur") et les fonctions consommatrices (les "fans"), lesquels recevront un résultat ou une erreur. Ces fonctions consommatrices peuvent s'abonner (subscribed) utilisant les méthodes `.then`, `.catch`.
133
+
Un objet promesse permet le lien entre l'exécuteur (le "code produit" ou "chanteur") et les fonctions consommatrices (les "fans"), lesquels recevront un résultat ou une erreur. Ces fonctions consommatrices peuvent s'abonner (subscribed) en utilisant les méthodes `.then`, `.catch`.
132
134
133
135
### then (alors)
134
136
@@ -147,7 +149,7 @@ Le premier argument de `.then` est une fonction qui se lance si la promesse est
147
149
148
150
Le deuxième argument de `.then` est une fonction qui se lance si la promesse est rompue, et reçoit l'erreur.
149
151
150
-
Par exemple, voyons la réponse à un une requête correctement tenue :
152
+
Par exemple, voyons la réponse à une requête correctement tenue :
151
153
152
154
```js run
153
155
let promise = new Promise(function(resolve, reject) {
@@ -180,7 +182,7 @@ promise.then(
180
182
*/!*
181
183
);
182
184
```
183
-
Si nous sommes seulement intéressés aux promesses tenues, nous pouvons alors seulement fournir une fonction en argument à `.then` :
185
+
Si nous sommes seulement intéressés par les promesses tenues, nous pouvons alors seulement fournir une fonction en argument à `.then` :
184
186
185
187
```js run
186
188
let promise = new Promise(resolve => {
@@ -194,7 +196,7 @@ promise.then(alert); // affiche "done!" après 1 seconde
194
196
195
197
### catch
196
198
197
-
Si nous sommes seulement intéressés aux erreurs, alors nous pouvons mettre `null` comme premier argument : `.then(null, fonctionGerantLErreur)`. Ou nous pouvons utiliser `.catch(fonctionGerantLErreur)`, qui revient au même :
199
+
Si nous sommes seulement intéressés par les erreurs, alors nous pouvons mettre `null` comme premier argument : `.then(null, fonctionGerantLErreur)`. Ou nous pouvons utiliser `.catch(fonctionGerantLErreur)`, qui revient au même :
198
200
199
201
```js run
200
202
let promise = new Promise((resolve, reject) => {
@@ -207,13 +209,13 @@ promise.catch(alert); // affiche "Error: Whoops!" après 1 seconde
207
209
*/!*
208
210
```
209
211
210
-
L'appel à `.catch(f)` est complétement analogue à `.then(null, f)`, c'est juste un raccourci.
212
+
L'appel à `.catch(f)` est complètement analogue à `.then(null, f)`, c'est juste un raccourci.
211
213
212
214
## Cleanup: finally
213
215
214
216
Comme il y a un terme `finally` dans un `try {...} catch {...}`, il y a des `finally` dans les promesses.
215
217
216
-
L'appel à `.finally(f)` est similaire à `.then(f, f)` dans le sens où `f` se lance toujours quand la promesse est aquittée : qu'elle soit tenue ou rompue.
218
+
L'appel à `.finally(f)` est similaire à `.then(f, f)` dans le sens où `f` se lance toujours quand la promesse est aquittée : qu'elle soit tenue ou rompue.
217
219
218
220
L'idée de `finally` est de configurer un gestionnaire pour effectuer le nettoyage/la finalisation une fois les opérations précédentes terminées.
219
221
@@ -256,7 +258,7 @@ Il existe des différences importantes :
256
258
257
259
Comme vous pouvez le voir, la `value` renvoyée par la première promesse est transmise par `finally` au prochain `then`.
258
260
259
-
C'est très pratique, car `finaly` n'est pas destiné à traiter un résultat de promesse. Comme dit, c'est un endroit pour faire un nettoyage générique, quel que soit le résultat.
261
+
C'est très pratique, car `finally` n'est pas destiné à traiter un résultat de promesse. Comme déjà dit, c'est un endroit pour faire un nettoyage générique, quel que soit le résultat.
260
262
261
263
Et voici un exemple d'erreur, pour que nous puissions voir comment elle est passée de `finally` à `catch` :
262
264
@@ -270,7 +272,7 @@ Il existe des différences importantes :
270
272
271
273
3. Un gestionnaire `finally` ne devrait pas non plus renvoyer quoi que ce soit. Si c'est le cas, la valeur renvoyée est silencieusement ignorée.
272
274
273
-
La seule exception à cette règle est lorsqu'un gestionnaire `finally` génère une erreur. Ensuite, cette erreur passe au gestionnaire suivant, au lieu de tout résultat précédent.
275
+
La seule exception à cette règle est lorsqu'un gestionnaire `finally` génère une erreur. Ensuite, cette erreur passe au gestionnaire suivant, à la place de tout résultat précédent.
274
276
275
277
Pour résumer :
276
278
@@ -319,7 +321,7 @@ function loadScript(src, callback) {
319
321
}
320
322
```
321
323
322
-
Re-écrivonsla avec une promesse.
324
+
Re-écrivons-la avec une promesse.
323
325
324
326
La nouvelle fonction `loadScript` ne nécessite aucune fonction de retour. À la place, elle va créer et retournera une promesse qui s'acquittera lorque le chargement sera complet. Le code externe peut ajouter des gestionnaires (fonction s'abonnant) à celle-ci en utilisant `.then`.
325
327
@@ -354,7 +356,7 @@ On peut remarquer immédiatement quelques avantages par rapport aux fonctions de
354
356
355
357
| Promesses | Fonctions de retour |
356
358
|-----------|----------------------|
357
-
| Les promesses nous permettent de faire des choses dans un ordre naturel. D'abord, nous lançons `loadScript(script)`, puis avec `.then` nous codons quoi faire avec le résultat. | Nous devons avoir une fonction de retour à notre disposition quand nous appelons `loadScript(script, callback)`. En d'autres mots, nous devons savoir quoi faire du résultat *avant* que `loadScript`est appelé. |
358
-
| Nous pouvons appeler `.then` sur une promesse autant de temps fois que nécessaires. À chaque fois, nous ajoutons un nouveau "fan", une nouvelle fonction s'abonnant à la "liste d'abonnés". Nous en verrons plus à ce sujet dans le prochain chapitre : [](info:promise-chaining). | Il ne peut y avoir qu'une seule fonction de retour. |
359
+
| Les promesses nous permettent de faire des choses dans un ordre naturel. D'abord, nous lançons `loadScript(script)`, puis avec `.then` nous codons quoi faire avec le résultat. | Nous devons avoir une fonction de retour à notre disposition quand nous appelons `loadScript(script, callback)`. En d'autres termes, nous devons savoir quoi faire du résultat *avant* que `loadScript`soit appelé. |
360
+
| Nous pouvons appeler `.then` sur une promesse autant de temps fois que nécessaire. À chaque fois, nous ajoutons un nouveau "fan", une nouvelle fonction s'abonnant à la "liste d'abonnés". Nous en verrons plus à ce sujet dans le prochain chapitre : [](info:promise-chaining). | Il ne peut y avoir qu'une seule fonction de retour. |
359
361
360
362
Les promesses nous permettent donc d'avoir plus de sens et une meilleure flexibilité. Mais il y a plus. Nous allons voir cela dans les chapitres suivants.
Copy file name to clipboardExpand all lines: 2-ui/99-ui-misc/03-event-loop/article.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -260,7 +260,7 @@ alert("code");
260
260
Quel sera l'ordre ici?
261
261
262
262
1.`code` s'affiche en premier, car il s'agit d'un appel synchrone régulier.
263
-
2.`promesse` s'affiche en second, car `.then` passe par la file d'attente des microtâches et s'exécute après le code actuel.
263
+
2.`promise` s'affiche en second, car `.then` passe par la file d'attente des microtâches et s'exécute après le code actuel.
264
264
3.`timeout` s'affiche en dernier, car c'est une macrotâche.
265
265
266
266
Une image, plus parlante, de la boucle d'événements ressemble à ceci (l'ordre est de haut en bas, c'est-à-dire: le script d'abord, puis les microtâches, le rendu, etc.):
0 commit comments