aboutsummaryrefslogtreecommitdiff
path: root/files/fr/learn/javascript/asynchronous/choosing_the_right_approach/index.html
blob: 0b71c56c49d0bf4c205924d44e6f3d1bbcc022f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
---
title: Choisir la bonne approche
slug: Learn/JavaScript/Asynchronous/Choosing_the_right_approach
tags:
  - Beginner
  - Intervals
  - JavaScript
  - Learn
  - Optimize
  - Promises
  - async
  - asynchronous
  - await
  - requestAnimationFrame
  - setInterval
  - setTimeout
  - timeouts
translation_of: Learn/JavaScript/Asynchronous/Choosing_the_right_approach
---
<div>{{LearnSidebar}}</div>

<div>{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}</div>

<p>Pour terminer ce module, nous vous proposons une brève discussion sur les différentes techniques et fonctionnalités asynchrones abordées tout au long de ce module, en examinant laquelle de ces techniques est la plus pertinente en fonction de la situation ainsi que des recommandations et des rappels des pièges courants le cas échéant.</p>

<table class="standard-table">
  <tbody>
    <tr>
      <th scope="row">Prérequis :</th>
      <td>Connaissances informatiques de base, une compréhension raisonnable des principes fondamentaux de JavaScript.</td>
    </tr>
    <tr>
      <th scope="row">Objectif :</th>
      <td>Être capable de faire un choix judicieux quant à l'utilisation de différentes techniques de programmation asynchrone.</td>
    </tr>
  </tbody>
</table>

<h2 id="asynchronous_callbacks">Fonctions de rappels (callbacks) asynchrones</h2>

<p>Généralement trouvé dans les API à l'ancienne, une fonction de rappel (ou <i>callback</i> en anglais) implique qu'une fonction soit passée en paramètre à une autre fonction, qui est ensuite invoquée lorsqu'une opération asynchrone est terminée afin réaliser une opération avec le résultat. C'est la méthode qui précédait l'arrivée des promesses : elle n'est pas aussi efficace ou flexible. Ne l'utilisez que si nécessaire.</p>

<table class="standard-table">
  <caption>Utile pour…</caption>
  <thead>
    <tr>
      <th scope="col">Opération unique retardée</th>
      <th scope="col">Opération répétée</th>
      <th scope="col">Opérations séquentielles multiples</th>
      <th scope="col">Opérations simultanées multiples</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>Oui (rappels récursifs)</td>
      <td>Oui (rappels imbriqués)</td>
      <td>Non</td>
    </tr>
  </tbody>
</table>

<h3 id="code_example">Exemple de code</h3>

<p>Un exemple qui charge une ressource via l'API <a href="/fr/docs/Web/API/XMLHttpRequest"><code>XMLHttpRequest</code></a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/xhr-async-callback.html">l'exécuter en direct</a>, et <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/xhr-async-callback.html">voir la source</a>) :</p>

<pre class="brush: js">function loadAsset(url, type, callback) {
  let xhr = new XMLHttpRequest();
  xhr.open('GET', url);
  xhr.responseType = type;

  xhr.onload = function() {
    callback(xhr.response);
  };

  xhr.send();
}

function displayImage(blob) {
  let objectURL = URL.createObjectURL(blob);

  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
}

loadAsset('coffee.jpg', 'blob', displayImage);</pre>

<h3 id="pitfalls">Pièges</h3>

<ul>
  <li>Les fonctions de rappels imbriquées peuvent être encombrantes et difficiles à lire (ce qu'on appelle parfois « <i>callback hell</i> » en anglais).</li>
  <li>Les fonctions de rappel pour les cas d'erreur doivent être appelés une fois pour chaque niveau d'imbrication, alors qu'avec les promesses, vous pouvez simplement utiliser un seul bloc <code>.catch()</code> pour gérer les erreurs de toute la chaîne.</li>
  <li>Les fonctions de rappel asynchrones ne sont pas très élégantes.</li>
  <li>Les fonctions de rappel passées en argument de promesses sont toujours appelés dans l'ordre strict où ils sont placés dans la file d'attente des événements ; les fonctions de rappel asynchrones ne le sont pas.</li>
  <li>Les fonctions de rappel asynchrones perdent le contrôle total de la façon dont la fonction sera exécutée lorsqu'elle est transmise à une bibliothèque tierce.</li>
</ul>

<h3 id="browser_compatibility">Compatibilité des navigateurs</h3>

<p>Très bonne prise en charge générale, bien que la prise en charge exacte dans les différentes API dépende de l'API en question. Reportez-vous à la documentation de référence de l'API que vous utilisez pour obtenir des informations plus spécifiques.</p>

<h3 id="further_information">Plus d'informations</h3>

<ul>
  <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Introducing">Introduction au JavaScript asynchrone</a>, en particulier les <a href="/fr/docs/Learn/JavaScript/Asynchronous/Introducing#async_callbacks">Fonctions de rappels asynchrones</a></li>
</ul>

<h2 id="settimeout">setTimeout()</h2>

<p><a href="/fr/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout"><code>setTimeout()</a></code> est une méthode qui permet d'exécuter une fonction après l'écoulement d'un délai arbitraire.</p>

<table class="standard-table">
  <caption>Utile pour…</caption>
  <thead>
    <tr>
      <th scope="col">Opération unique retardée</th>
      <th scope="col">Opération répétée</th>
      <th scope="col">Opérations séquentielles multiples</th>
      <th scope="col">Opérations simultanées multiples</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Oui</td>
      <td>Oui (délais récursifs)</td>
      <td>Oui (délais d'attente imbriqués)</td>
      <td>Non</td>
    </tr>
  </tbody>
</table>

<h3 id="code_example_2">Exemple de code</h3>

<p>Ici, le navigateur attendra deux secondes avant d'exécuter la fonction anonyme, puis affichera le message dans la console (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/simple-settimeout.html">voir son exécution en direct</a>, et <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/simple-settimeout.html">voir le code source</a>) :</p>

<pre class="brush: js">let myGreeting = setTimeout(function() {
  console.log('Bonjour, M. Univers !');
}, 2000)</pre>

<h3 id="pitfalls_2">Pièges</h3>

<p>Vous pouvez utiliser des appels récursifs à <code>setTimeout()</code> pour exécuter une fonction de manière répétée de façon similaire à <code>setInterval()</code>, en utilisant un code comme celui-ci :</p>

<pre class="brush: js">let i = 1;
setTimeout(function run() {
  console.log(i);
  i++;

  setTimeout(run, 100);
}, 100);</pre>

<p>Il existe une différence entre <code>setTimeout()</code> appelé récursivement et <code>setInterval()</code> :</p>

<ul>
  <li>Les récursions avec <code>setTimeout()</code> garantissent qu'au moins le temps spécifié (100ms dans cet exemple) s'écoulera entre les exécutions ; le code s'exécutera puis attendra 100 millisecondes avant de s'exécuter à nouveau. L'intervalle sera le même quelle que soit la durée d'exécution du code.</li>
  <li>Avec <code>setInterval()</code>, l'intervalle que nous choisissons <em>inclut</em> le temps d'exécution du code que nous voulons exécuter. Disons que le code prend 40 millisecondes pour s'exécuter — l'intervalle finit alors par n'être que de 60 millisecondes.</li>
</ul>

<p>Lorsque votre code a le potentiel de prendre plus de temps à s'exécuter que l'intervalle de temps que vous avez assigné, il est préférable d'utiliser <code>setTimeout()</code> récursivement - cela maintiendra l'intervalle de temps constant entre les exécutions, quelle que soit la durée d'exécution du code, et vous n'obtiendrez pas d'erreurs.</p>

<h3 id="browser_compatibility_2">Compatibilité des navigateurs</h3>

<p>{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}</p>

<h3 id="further_information_2">Plus d'informations</h3>

<ul>
  <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">JavaScript asynchrone coopératif : Délais et intervalles</a>, en particulier <a href="/fr/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals#settimeout()"><code>setTimeout()</code></a></li>
  <li>Page de référence pour <a href="/fr/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout"><code>setTimeout()</code></a></li>
</ul>

<h2 id="setInterval">setInterval()</h2>

<p><a href="/fr/docs/Web/API/WindowOrWorkerGlobalScope/setInterval"><code>setInterval()</code></a> est une méthode qui permet d'exécuter une fonction de façon répétée avec des intervalles de temps donnés entre chaque exécution. Cette méthode n'est pas aussi efficace que <a href="/fr/docs/Web/API/Window/requestAnimationFrame"><code>requestAnimationFrame()</code></a>, mais elle permet de choisir le rythme d'exécution.</p>

<table class="standard-table">
  <caption>Utile pour…</caption>
  <thead>
    <tr>
      <th scope="col">Opération unique retardée</th>
      <th scope="col">Opération répétée</th>
      <th scope="col">Opérations séquentielles multiples</th>
      <th scope="col">Opérations simultanées multiples</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>Oui</td>
      <td>Non (à moins qu'elles ne soient les mêmes)</td>
      <td>Non</td>
    </tr>
  </tbody>
</table>

<h3 id="code_example_3">Exemple de code</h3>

<p>La fonction suivante crée un nouvel objet <a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Date"><code>Date()</code></a>, en extrait une chaîne de temps à l'aide de <a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString"><code>toLocaleTimeString()</code></a>, puis l'affiche dans l'interface utilisateur. Nous l'exécutons ensuite une fois par seconde à l'aide de <code>setInterval()</code>, créant l'effet d'une horloge numérique qui se met à jour une fois par seconde (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">voir cela en direct</a>, et aussi <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">voir la source</a>) :</p>

<pre class="brush: js">function displayTime() {
  let date = new Date();
  let time = date.toLocaleTimeString();
  document.getElementById('demo').textContent = time;
}

const createClock = setInterval(displayTime, 1000);</pre>

<h3 id="pitfalls_3">Pièges</h3>

<ul>
 <li>La fréquence d'exécution et d'affichage n'est pas optimisée pour le système sur lequel l'animation est exécutée, et peut être quelque peu inefficace. À moins que vous n'ayez besoin de choisir un framerate spécifique (plus lent), il est généralement préférable d'utiliser <code>requestAnimationFrame()</code>.</li>
</ul>

<h3 id="browser_compatibility_3">Compatibilité des navigateurs</h3>

<p>{{Compat("api.WindowOrWorkerGlobalScope.setInterval")}}</p>

<h3 id="further_information_3">Plus d'informations</h3>

<ul>
  <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">JavaScript asynchrone coopératif : Délais et intervalles</a>, en particulier <a href="/fr/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a></li>
  <li>Page de référence pour <a href="/fr/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a></li>
</ul>

<h2 id="requestAnimationFrame">requestAnimationFrame()</h2>

<p><a href="/fr/docs/Web/API/Window/requestAnimationFrame"><code>requestAnimationFrame()</code></a> est une méthode qui vous permet d'exécuter une fonction de manière répétée, et efficace, à la meilleure fréquence de rafraîchissement disponible compte tenu du navigateur/système actuel. Vous devriez, dans la mesure du possible, utiliser cette méthode au lieu de <code>setInterval()</code>/<code>setTimeout()</code> récursif, sauf si vous avez besoin d'une fréquence de rafraîchissement spécifique.</p>

<table class="standard-table">
  <caption>Utile pour…</caption>
  <thead>
    <tr>
      <th scope="col">Opération unique retardée</th>
      <th scope="col">Opération répétée</th>
      <th scope="col">Opérations séquentielles multiples</th>
      <th scope="col">Opérations simultanées multiples</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>Oui</td>
      <td>Non (à moins que ce soit les mêmes)</td>
      <td>Non</td>
    </tr>
  </tbody>
</table>

<h3 id="code_example_4">Exemple de code</h3>

<p>Une toupie animée simple ; vous pouvez trouver cet <a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/simple-raf-spinner.html">exemple en direct sur GitHub</a> (voir le <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/simple-raf-spinner.html">code source</a>) :</p>

<pre class="brush: js">const spinner = document.querySelector('div');
let rotateCount = 0;
let startTime = null;
let rAF;

function draw(timestamp) {
  if(!startTime) {
    startTime = timestamp;
  }

  rotateCount = (timestamp - startTime) / 3;

  if(rotateCount &gt; 359) {
    rotateCount %= 360;
  }

  spinner.style.transform = 'rotate(' + rotateCount + 'deg)';

  rAF = requestAnimationFrame(draw);
}

draw();</pre>

<h3 id="pitfalls_4">Pièges</h3>

<ul>
  <li>Vous ne pouvez pas choisir une fréquence d'images spécifique avec <code>requestAnimationFrame()</code>. Si vous devez exécuter votre animation à un <i>framerate</i> plus lent, vous devrez utiliser <code>setInterval()</code> ou <code>setTimeout()</code> récursif.</li>
</ul>

<h3 id="browser_compatibility_4">Compatibilité des navigateurs</h3>

<p>{{Compat("api.Window.requestAnimationFrame")}}</p>

<h3 id="further_information_4">Plus d'informations</h3>

<ul>
  <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">JavaScript asynchrone coopératif : Délais et intervalles</a>, en particulier <a href="/fr/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals#requestanimationframe()"><code>requestAnimationFrame()</code></a></li>
 <li>Page de référence pour <a href="/fr/docs/Web/API/Window/requestAnimationFrame"><code>requestAnimationFrame()</code></a></li>
</ul>

<h2 id="Promises">Promises (Promesses)</h2>

<p><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Promise">Les promesses</a> sont une fonctionnalité JavaScript qui permet d'exécuter des opérations asynchrones et d'attendre qu'elles soient définitivement terminées avant d'exécuter une autre opération en fonction de son résultat. Les promesses sont la colonne vertébrale du JavaScript asynchrone moderne.</p>

<table class="standard-table">
  <caption>Utile pour…</caption>
  <thead>
    <tr>
      <th scope="col">Opération unique retardée</th>
      <th scope="col">Opération répétée</th>
      <th scope="col">Opérations séquentielles multiples</th>
      <th scope="col">Opérations simultanées multiples</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>Non</td>
      <td>Oui</td>
      <td>Voir <code>Promise.all()</code>, en dessous</td>
    </tr>
  </tbody>
</table>

<h3 id="code_example_5">Exemple de code</h3>

<p>Le code suivant va chercher une image sur le serveur et l'affiche à l'intérieur d'un élément <a href="/fr/docs/Web/HTML/Element/Img"><code>&lt;img&gt;</code></a> ; <a href="https://mdn.github.io/learning-area/javascript/asynchronous/promises/simple-fetch-chained.html">voyez-le aussi en direct</a>, et voyez aussi <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/simple-fetch-chained.html">le code source</a> :</p>

<pre class="brush: js">fetch('coffee.jpg')
.then(response =&gt; response.blob())
.then(myBlob =&gt; {
  let objectURL = URL.createObjectURL(myBlob);
  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
})
.catch(e =&gt; {
  console.log('Il y a eu un problème avec votre opération de récupération : ' + e.message);
});</pre>

<h3 id="pitfalls_5">Pièges</h3>

<p>Les chaînes de promesses peuvent être complexes et difficiles à analyser. Si vous imbriquez un certain nombre de promesses, vous pouvez vous retrouver avec des problèmes similaires à l'enfer des rappels. Par exemple :</p>

<pre class="brush: js">remotedb.allDocs({
  include_docs: true,
  attachments: true
}).then(function (result) {
  let docs = result.rows;
  docs.forEach(function(element) {
    localdb.put(element.doc).then(function(response) {
      alert("Un document extrait avec un id " + element.doc._id + " et ajouté à la base de données locale.");
    }).catch(function (err) {
      if (err.name == 'conflict') {
        localdb.get(element.doc._id).then(function (resp) {
          localdb.remove(resp._id, resp._rev).then(function (resp) {
// et cetera...</pre>

<p>Il est préférable d'utiliser la puissance de chaînage des promesses pour aller avec une structure plus plate et plus facile à analyser :</p>

<pre class="brush: js">remotedb.allDocs(...).then(function (resultOfAllDocs) {
  return localdb.put(...);
}).then(function (resultOfPut) {
  return localdb.get(...);
}).then(function (resultOfGet) {
  return localdb.put(...);
}).catch(function (err) {
  console.log(err);
});</pre>

<p>ou encore :</p>

<pre class="brush: js">remotedb.allDocs(...)
.then(resultOfAllDocs =&gt; {
  return localdb.put(...);
})
.then(resultOfPut =&gt; {
  return localdb.get(...);
})
.then(resultOfGet =&gt; {
  return localdb.put(...);
})
.catch(err =&gt; console.log(err));</pre>

<p>Cela couvre une grande partie des éléments de base. Pour un traitement beaucoup plus complet, voir l'excellent article <a href="https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html">Nous avons un problème avec les promesses</a> <small>(en)</small>, par Nolan Lawson.</p>

<h3 id="browser_compatibility_5">Compatibilité des navigateurs</h3>

<p>{{Compat("javascript.builtins.Promise")}}</p>

<h3 id="further_information_5">Plus d'informations</h3>

<ul>
 <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Promises">Gérer les opérations asynchrones avec élégance grâce aux Promesses</a></li>
 <li><a href="/fr/docs/Web/JavaScript/Guide/Using_promises">Utiliser les promesses</a></li>
 <li>Page de référence pour <a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Promise"><code>Promise</code></a></li>
</ul>

<h2 id="Promise.all">Promise.all()</h2>

<p>Une fonction JavaScript qui vous permet d'attendre que plusieurs promesses se terminent avant d'exécuter une autre opération basée sur les résultats de toutes les autres promesses.</p>

<table class="standard-table">
  <caption>Utile pour…</caption>
  <thead>
    <tr>
      <th scope="col">Opération unique retardée</th>
      <th scope="col">Opération répétée</th>
      <th scope="col">Opérations séquentielles multiples</th>
      <th scope="col">Opérations simultanées multiples</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>Non</td>
      <td>Non</td>
      <td>Oui</td>
    </tr>
  </tbody>
</table>

<h3 id="code_example_6">Exemple de code</h3>

<p>L'exemple suivant va chercher plusieurs ressources sur le serveur, et utilise <code>Promise.all()</code> pour attendre qu'elles soient toutes disponibles avant de les afficher toutes — <a href="https://mdn.github.io/learning-area/javascript/asynchronous/promises/promise-all.html">le voir fonctionner</a>, et voir son <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/promise-all.html">code source</a> :</p>

<pre class="brush: js">function fetchAndDecode(url, type) {
  // Retourner la promesse de niveau supérieur, de sorte que le résultat
  // de l'ensemble de la chaîne est retourné hors de la fonction
  return fetch(url).then(response =&gt; {
    // Selon le type de fichier recherché, utilisez la fonction appropriée pour décoder son contenu
    if(type === 'blob') {
      return response.blob();
    } else if(type === 'text') {
      return response.text();
    }
  })
  .catch(e =&gt; {
    console.log(`Il y a eu un problème avec votre opération de récupération de la ressource "${url}" : ` + e.message);
  });
}

// Appeler la méthode fetchAndDecode() pour récupérer les images et le texte
// et stocker leurs promesses dans des variables
let coffee = fetchAndDecode('coffee.jpg', 'blob');
let tea = fetchAndDecode('tea.jpg', 'blob');
let description = fetchAndDecode('description.txt', 'text');

// Utiliser Promise.all() pour exécuter le code uniquement lorsque
// les trois appels de fonction ont été résolus
Promise.all([coffee, tea, description]).then(values =&gt; {
  console.log(values);
  // Stocker chaque valeur retournée par les promesses dans des variables séparées ;
  // créer des URL d'objets à partir des blobs.
  let objectURL1 = URL.createObjectURL(values[0]);
  let objectURL2 = URL.createObjectURL(values[1]);
  let descText = values[2];

  // Afficher les images dans les éléments &lt;img&gt;
  let image1 = document.createElement('img');
  let image2 = document.createElement('img');
  image1.src = objectURL1;
  image2.src = objectURL2;
  document.body.appendChild(image1);
  document.body.appendChild(image2);

  // Afficher le texte d'un paragraphe
  let para = document.createElement('p');
  para.textContent = descText;
  document.body.appendChild(para);
});</pre>

<h3 id="pitfalls_6">Pièges</h3>

<ul>
  <li>Si <code>Promesse.all()</code> est rejeté, alors une ou plusieurs des promesses que vous lui fournissez dans son paramètre de tableau doivent être rejetées, ou pourraient ne pas retourner de promesses du tout. Vous devez vérifier chacune d'entre elles pour voir ce qu'elles ont retourné.</li>
</ul>

<h3 id="browser_compatibility_6">Compatibilité des navigateurs</h3>

<p>{{Compat("javascript.builtins.Promise.all")}}</p>

<h3 id="further_information_6">Plus d'informations</h3>

<ul>
 <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Promises#running_code_in_response_to_multiple_promises_fulfilling">Gérer les opérations asynchrones avec élégance grâce aux Promesses</a></li>
 <li>Page de référence pour <a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Promise/all"><code>Promise.all()</code></a></li>
</ul>

<h2 id="Asyncawait">async/await</h2>

<p>Un outil syntaxique construit sur les promesses qui vous permet d'exécuter des opérations asynchrones en utilisant une syntaxe qui ressemble plus à l'écriture de code de rappel synchrone.</p>

<table class="standard-table">
  <caption>Utile pour…</caption>
  <thead>
    <tr>
      <th scope="col">Opération unique retardée</th>
      <th scope="col">Opération répétée</th>
      <th scope="col">Opérations séquentielles multiples</th>
      <th scope="col">Opérations simultanées multiples</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>Non</td>
      <td>Oui</td>
      <td>Oui (en combinaison avec <code>Promise.all()</code>)</td>
    </tr>
  </tbody>
</table>

<h3 id="code_example_7">Exemple de code</h3>

<p>L'exemple suivant est un remaniement de l'exemple simple de promesse que nous avons vu précédemment, qui récupère et affiche une image, écrit à l'aide d'async/await (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/async-await/simple-refactored-fetch.html">voir en direct</a>, et voir le <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/async-await/simple-refactored-fetch.html">code source</a>) :</p>

<pre class="brush: js">async function myFetch() {
  let response = await fetch('coffee.jpg');
  let myBlob = await response.blob();

  let objectURL = URL.createObjectURL(myBlob);
  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
}

myFetch();</pre>

<h3 id="pitfalls_7">Pièges</h3>

<ul>
  <li>Vous ne pouvez pas utiliser l'opérateur <code>await</code> à l'intérieur d'une fonction non-<code>async</code>, ou dans le contexte de haut niveau de votre code. Cela peut parfois entraîner la création d'une fonction encapsulante supplémentaire, ce qui peut être légèrement frustrant dans certaines circonstances. Mais cela en vaut la peine la plupart du temps.</li>
  <li>Le support des navigateurs pour <code>async</code>/<code>await</code> n'est pas aussi bon que celui des promesses. Si vous souhaitez utiliser <code>async</code>/<code>await</code> mais que vous êtes préoccupé par la prise en charge de navigateurs plus anciens, vous pouvez envisager d'utiliser la bibliothèque <a href="https://babeljs.io/">BabelJS</a> — cela vous permet d'écrire vos applications en utilisant le JavaScript le plus récent et de laisser Babel déterminer les modifications éventuellement nécessaires pour les navigateurs de vos utilisateurs.</li>
</ul>

<h3 id="browser_compatibility_7">Compatibilité des navigateurs</h3>

<p>{{Compat("javascript.statements.async_function")}}</p>

<h3 id="further_information_7">Plus d'informations</h3>

<ul>
 <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Async_await">Faciliter la programmation asynchrone avec <code>async</code> et <code>await</code></a></li>
 <li>Page de référence pour <a href="/fr/docs/Web/JavaScript/Reference/Statements/async_function">les fonctions asynchrones</a></li>
 <li>Page de référence pour l'opérateur <a href="/fr/docs/Web/JavaScript/Reference/Operators/await">await</a></li>
</ul>

<p>{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}</p>

<h2 id="In_this_module">Dans ce module</h2>

<ul>
  <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Concepts">Concepts généraux de programmation asynchrone</a></li>
  <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Introducing">Introduction au JavaScript asynchrone</a></li>
  <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">JavaScript asynchrone coopératif : Délais et intervalles</a></li>
  <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Promises">Gérer les opérations asynchrones avec élégance grâce aux Promesses</a></li>
  <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Async_await">Faciliter la programmation asynchrone avec <code>async</code> et <code>await</code></a></li>
  <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Choisir la bonne approche</a></li>
</ul>