diff options
author | Florian Merz <me@fiji-flo.de> | 2021-02-11 12:36:08 +0100 |
---|---|---|
committer | Florian Merz <me@fiji-flo.de> | 2021-02-11 12:36:08 +0100 |
commit | 39f2114f9797eb51994966c6bb8ff1814c9a4da8 (patch) | |
tree | 66dbd9c921f56e440f8816ed29ac23682a1ac4ef /files/fr/web/javascript/reference/global_objects/promise | |
parent | 8260a606c143e6b55a467edf017a56bdcd6cba7e (diff) | |
download | translated-content-39f2114f9797eb51994966c6bb8ff1814c9a4da8.tar.gz translated-content-39f2114f9797eb51994966c6bb8ff1814c9a4da8.tar.bz2 translated-content-39f2114f9797eb51994966c6bb8ff1814c9a4da8.zip |
unslug fr: move
Diffstat (limited to 'files/fr/web/javascript/reference/global_objects/promise')
10 files changed, 1641 insertions, 0 deletions
diff --git a/files/fr/web/javascript/reference/global_objects/promise/all/index.html b/files/fr/web/javascript/reference/global_objects/promise/all/index.html new file mode 100644 index 0000000000..4cc24f3cc5 --- /dev/null +++ b/files/fr/web/javascript/reference/global_objects/promise/all/index.html @@ -0,0 +1,226 @@ +--- +title: Promise.all() +slug: Web/JavaScript/Reference/Objets_globaux/Promise/all +tags: + - ECMAScript 2015 + - JavaScript + - Méthode + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/all +--- +<div>{{JSRef}}</div> + +<p>La méthode <code><strong>Promise.all()</strong></code> renvoie une promesse ({{jsxref("Promise")}}) qui est résolue lorsque l'ensemble des promesses contenues dans l'itérable passé en argument ont été résolues ou qui échoue avec la raison de la première promesse qui échoue au sein de l'itérable.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-all.html")}}</div> + +<p class="hidden">Le code source de cet exemple interactif est disponible dans un dépôt GitHub. Si vous souhaitez contribuez à ces exemples, n'hésitez pas à cloner <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> et à envoyer une <em>pull request</em> !</p> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="syntaxbox">Promise.all(<var>iterable</var>);</pre> + +<h3 id="Paramètres">Paramètres</h3> + +<dl> + <dt><code>iterable</code></dt> + <dd>Un objet <a href="/fr/docs/Web/JavaScript/Reference/Les_protocoles_iteration#Le_protocole_«_itérable_»">itérable</a> (tel qu'un tableau ({{jsxref("Array")}})) contenant des promesses.</dd> +</dl> + +<h3 id="Valeur_de_retour">Valeur de retour</h3> + +<p>Un objet {{jsxref("Promise")}} qui est</p> + +<ul> + <li>résolue immédiatement si l'itérable passé en argument est vide</li> + <li>résolue de façon asynchrone si l'itérable passé en argument ne contient aucune promesse (Chrome 58 renvoie immédiatement une promesse résolue dans ce cas)</li> + <li>en attente de résolution asynchrone dans les autres cas.</li> +</ul> + +<h2 id="Description">Description</h2> + +<p>Cette méthode peut être utile lorsqu'on souhaite agréger le résultat de plusieurs promesses.</p> + +<dl> + <dt>Valeur de résolution</dt> + <dd>Si toutes les promesses de l'itérable sont tenues, <code>Promise.all</code> est tenue et la valeur de résolution est un tableau qui contient les valeurs de résolution respectives des promesses de l'itérable (dans le même ordre). Si l'argument utilisé est un tableau vide, la méthode résoud la promesse immédiatement et de façon synchrone.</dd> + <dt>Valeur d'échec</dt> + <dd>Si l'une des promesses de l'itérable échoue, <code>Promise.all</code> échoue immédiatement et utilise la raison de l'échec (que les autres promesses aient été résolues ou non).</dd> +</dl> + +<h2 id="Exemples">Exemples</h2> + +<h3 id="Utiliser_Promise.all()">Utiliser <code>Promise.all()</code></h3> + +<p><code>Promise.all()</code> attend que l'ensemble des promesses soient tenues ou qu'une promesse soit rompue :</p> + +<pre class="brush: js">var p1 = Promise.resolve(3); +var p2 = 1337; +var p3 = new Promise((resolve, reject) => { + setTimeout(resolve, 100, 'foo'); +}); + +Promise.all([p1, p2, p3]).then(values => { + console.log(values); // [3, 1337, "foo"] +});</pre> + +<h3 id="Promise.all()_un_échec_rapide"><code>Promise.all()</code>, un échec rapide</h3> + +<p>La promesse créée par <code>Promise.all()</code> échoue immédiatement si l'une des promesses échoue. Dans l'exemple suivant, on fournit quatre promesses qui sont résolues après une certaine durée et une autre promesse qui est rompue immédiatement : on peut alors voir que la promesse créée par <code>Promise.all()</code> est rompue immédiatement.</p> + +<pre class="brush: js">var p1 = new Promise((resolve, reject) => { + setTimeout(resolve, 1000, 'un'); +}); +var p2 = new Promise((resolve, reject) => { + setTimeout(resolve, 2000, 'deux'); +}); +var p3 = new Promise((resolve, reject) => { + setTimeout(resolve, 3000, 'trois'); +}); +var p4 = new Promise((resolve, reject) => { + setTimeout(resolve, 4000, 'quatre'); +}); +var p5 = new Promise((resolve, reject) => { + reject('rejet'); +}); + +Promise.all([p1, p2, p3, p4, p5]).then(values => { + console.log(values); +}, reason => { + console.log(reason) +}); + +// Dans la console : +// "rejet" + +//On peut aussi employer .catch +Promise.all([p1, p2, p3, p4, p5]).then(values => { + console.log(values); +}).catch(reason => { + console.log(reason) +}); + +// Dans la console : +// "rejet" + +</pre> + +<p>Il est possible de modifier ce comportement en gérant les éventuels échecs :</p> + +<pre class="brush: js">var p1 = new Promise((resolve, reject) => { + setTimeout(resolve, 1000, 'p1_resolution_retardee'); +}); + +var p2 = new Promise((resolve, reject) => { + reject(new Error('p2_rejet_immediat')); +}); + +Promise.all([ + p1.catch(error => { return error }), + p2.catch(error => { return error }), +]).then(values => { + console.log(values[0]); // "p1_resolution_retardee" + console.log(values[1]); // "Error: p2_rejet_immediat" +}) +</pre> + +<h3 id="Caractère_asynchrone_de_Promise.all()">Caractère asynchrone de <code>Promise.all()</code></h3> + +<p>Dans l'exemple qui suit, on illustre le caractère asynchrone de <code>Promise.all()</code> (et son caractère synchrone quand l'itérable passé en argument est vide) :</p> + +<pre class="brush: js">// On passe un tableau de promesses déjà résolues +// afin de déclencher Promise.all dès que possible +var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)]; + +var p = Promise.all(resolvedPromisesArray); +// on affiche la valeur de p dans la console +console.log(p); + +// on utilise la méthode setTimeout pour exécuter +// du code dès que la pile est vide +setTimeout(function() { + console.log('La pile est vide'); + console.log(p); +}); + +// Cela affichera dans la console (et dans cet ordre) : +// Promise { <state>: "pending" } +// La pile est vide +// Promise { <state>: "fulfilled", <value>: Array[2] } +</pre> + +<p>On aura le même comportement si <code>Promise.all</code> produit une promesse rompue :</p> + +<pre class="brush: js">var mixedPromisesArray = [Promise.resolve(33), Promise.reject(44)]; +var p = Promise.all(mixedPromisesArray); +console.log(p); +setTimeout(function() { + console.log('La pile est vide'); + console.log(p); +}); + +// Affichera : +// Promise { <state>: "pending" } +// La pile est vide +// Promise { <state>: "rejected", <reason>: 44 } +</pre> + +<p>En revanche, <code>Promise.all</code> produit une promesse résolue de façon synchrone si et seulement si l'itérable est vide :</p> + +<pre class="brush: js">var p = Promise.all([]); // immédiatement résolue + +// les valeurs qui ne sont pas des promesses +// seront ignorées mais l'évaluation sera effectuée +// de façon asynchrone +var p2 = Promise.all([1337, "hi"]); +console.log(p); +console.log(p2) +setTimeout(function() { + console.log('La pile est vide'); + console.log(p2); +}); + +// Affichera : +// Promise { <state>: "fulfilled", <value>: Array[0] } +// Promise { <state>: "pending" } +// La pile est vide +// Promise { <state>: "fulfilled", <value>: Array[2] } +</pre> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Spécification</th> + <th scope="col">État</th> + <th scope="col">Commentaires</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ES2015', '#sec-promise.all', 'Promise.all')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Définition initiale dans un standard ECMA.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.all', 'Promise.all')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + +<p class="hidden">Pour contribuer à ces données de compatibilité, vous pouvez envoyer une <em>pull request</em> sur ce dépôt: <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p> + +<p>{{Compat("javascript.builtins.Promise.all")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.race()")}}</li> +</ul> diff --git a/files/fr/web/javascript/reference/global_objects/promise/allsettled/index.html b/files/fr/web/javascript/reference/global_objects/promise/allsettled/index.html new file mode 100644 index 0000000000..362df28f88 --- /dev/null +++ b/files/fr/web/javascript/reference/global_objects/promise/allsettled/index.html @@ -0,0 +1,66 @@ +--- +title: Promise.allSettled() +slug: Web/JavaScript/Reference/Objets_globaux/Promise/allSettled +tags: + - JavaScript + - Méthode + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/allSettled +--- +<p>{{JSRef}}</p> + +<p>La méthode <code><strong>Promise.allSettled()</strong></code> renvoie une promesse qui est résolue une fois que l'ensemble des promesses de l'itérable passée en argument sont réussies ou rejetées. La valeur de résolution de cette promesse est un tableau d'objets dont chacun est le résultat de chaque promesse de l'itérable.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-allsettled.html")}}</div> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="syntaxbox"><em>p</em>.allSettled(<em>iterable</em>);</pre> + +<h3 id="Paramètres">Paramètres</h3> + +<dl> + <dt><code>iterable</code></dt> + <dd>Un objet <a href="/fr/docs/Web/JavaScript/Reference/Les_protocoles_iteration">itérable</a> tel qu'un tableau ({{jsxref("Array")}}) dont chaque élément est une promesse ({{jsxref("Promise")}}.</dd> +</dl> + +<h3 id="Valeur_de_retour">Valeur de retour</h3> + +<p>Une promesse ({{jsxref("Promise")}}) <strong>en cours</strong> qui sera résolue de façon <strong>asynchrone</strong> une fois que chaque promesse de l'itérable a été résolue (tenue/réussie ou rejetée/échouée). Le gestionnaire passé à la promesse retournée recevra comme argument un tableau de valeur dont chacune est le résultat de chaque promesse de l'itérable initial.</p> + +<p>Pour chaque objet contenu dans ce tableau, il y aura une propriété <code>status</code> qui est une chaîne de caractères. Si <code>status</code> vaut <code>fulfilled</code>, alors on aura une propriété <code>value</code>. Si <code>status</code> vaut <code>rejected</code>, alors une propriété <code>reason</code> sera présente. La valeur (ou la raison) reflète la valeur de résolution de la promesse.</p> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Spécification</th> + <th scope="col">État</th> + <th scope="col">Commentaires</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="https://tc39.es/proposal-promise-allSettled/"><code>Promise.allSettled()</code> (Brouillon TC39 au niveau 4)</a></td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + +<div class="hidden">Le tableau de compatibilité de cette page a été généré à partir de données structurées. Si vous souhaitez contribuer à ces données, n'hésitez pas à consulter <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> et à nous envoyer une <em>pull request</em>.</div> + +<p>{{Compat("javascript.builtins.Promise.allSettled")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li><a href="/fr/docs/Web/JavaScript/Guide/Utiliser_les_promesses">Guide - Utiliser les promesses</a></li> + <li><a href="/fr/docs/Learn/JavaScript/Asynchronous/Promises">Programmation asynchrone à l'aide des promesses</a></li> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.all()")}}</li> +</ul> diff --git a/files/fr/web/javascript/reference/global_objects/promise/any/index.html b/files/fr/web/javascript/reference/global_objects/promise/any/index.html new file mode 100644 index 0000000000..7ce571e20c --- /dev/null +++ b/files/fr/web/javascript/reference/global_objects/promise/any/index.html @@ -0,0 +1,145 @@ +--- +title: Promise.any() +slug: Web/JavaScript/Reference/Objets_globaux/Promise/any +tags: + - JavaScript + - Method + - Méthode + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/any +--- +<div>{{JSRef}}</div> + +<p>La méthode <strong><code>Promise.any()</code></strong> prend comme argument un itérable contenant des objets {{JSxRef("Promise")}} et, dès qu'une des promesses de cet itérable est tenue, renvoie une unique promesse résolue avec la valeur de la promesse résolue. Si aucune promesse de l'itérable n'est tenue (c'est-à-dire si toutes les promesses sont rejetées), la promesse renvoyée est rompue avec un objet {{JSxRef("Objets_globaux/AggregateError", "AggregateError")}} (une nouvelle sous-classe de {{JSxRef("Error")}} qui regroupe un ensemble d'erreurs). Cette méthode fait essentiellement le <em>contraire</em> de {{JSxRef("Promise.all()")}} (qui renvoie une promesse tenue uniquement si toutes les promesses de l'itérable passé en argument ont été tenues).</p> + +<p>{{EmbedInteractiveExample("pages/js/promise-any.html")}}</p> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="notranslate">Promise.any(<var>iterable</var>);</pre> + +<h3 id="Paramètres">Paramètres</h3> + +<dl> + <dt><code>iterable</code></dt> + <dd>Un objet <a href="/fr/docs/Web/JavaScript/Reference/Les_protocoles_iteration">itérable</a> tel qu'un tableau ({{JSxRef("Array")}}) contenant des promesses ({{jsxref("Promise")}}).</dd> +</dl> + +<h3 id="Valeur_de_retour">Valeur de retour</h3> + +<ul> + <li>Une promesse ({{jsxref("Promise")}}) <strong>déjà résolue</strong> si l'itérable passé en argument est vide.</li> + <li>Une promesse ({{jsxref("Promise")}}) <strong>résolue en asynchrone</strong> si l'itérable passé en argument ne contient pas de promesses.</li> + <li>Une promesse ({{jsxref("Promise")}}) <strong>en attente</strong> dans tous les autres cas. La promesse renvoyée est résolue (qu'elle soit tenue ou rompue) <strong>de façon asynchrone</strong> lorsqu'au moins une des promesses de l'itérable est tenue ou si toutes les promesses ont été rompues.</li> +</ul> + +<h2 id="Description">Description</h2> + +<p>Cette méthode est utile afin de renvoyer la première promesse tenue d'un ensemble de promesse. Elle permet de court-circuiter dès qu'une promesse est tenue, sans attendre que les autres promesses soient résolues. Contrairement à {{JSxRef("Promise.all()")}} qui renvoie un tableau avec les valeurs de résolution des promesses, on a ici une seule valeur de résolution (celle de la première promesse tenue). Ce peut être bénéfique lorsqu'on a un ensemble de promesses et qu'on ne souhaite en résoudre qu'une sans se soucier de savoir laquelle des promesses a été tenue en premier.</p> + +<p>À la différence de {{JSxRef("Promise.race()")}} qui renvoie la valeur de la première promesse résolue (qu'elle ait été tenue ou rompue), <code>Promise.any()</code> renvoie une promesse avec la valeur de la première promesse <em>tenue</em>. Cette méthode ignore les promesses qui sont rompues jusqu'à obtenir une promesse tenue.</p> + +<h3 id="Une_des_promesses_est_tenue">Une des promesses est tenue</h3> + +<p>La promesse renvoyée par <code>Promise.any()</code> est résolue avec la première valeur résolue de l'itérable, qu'il s'agisse d'une promesse ou non, et que les autres promesses de l'itérable aient échoué ou non.</p> + +<ul> + <li>Si une des promesses de l'itérable (non vide) est tenue ou que les valeurs fournies dans l'itérable ne sont pas des promesses, alors la promesse renvoyée par <code>Promise.any()</code> est résolue de façon asynchrone.</li> +</ul> + +<h3 id="Toutes_les_promesses_sont_rompues">Toutes les promesses sont rompues</h3> + +<p>Si toutes les promesses de l'itérable échouent, <code>Promise.any()</code> échoue de asynchrone avec pour valeur d'échec un objet {{JSxRef("Objets_globaux/AggregateError", "AggregateError")}}, qui étend {{JSxRef("Error")}}, et contient une propriété <code>errors</code> qui est un tableau contenant l'ensemble des valeurs d'échec des différentes promesses de l'itérable.</p> + +<ul> + <li>Si l'itérable reçu était vide, alors la promesse retournée par cette méthode est rejetée de manière synchrone et la propriété <code>errors</code> de l'objet <code>AggregateError</code> est un tableau vide.</li> +</ul> + +<h2 id="Exemples">Exemples</h2> + +<h3 id="Première_résolue">Première résolue</h3> + +<p><code>Promise.any()</code> prend pour valeur de résolution celle de la première promesse résolue, et ce même si une des promesses de l'itérable a échoué avant. Ce comportement est différent de ce {{JSxRef("Promise.race()")}}, qui s'arrête à la première promesse qui se termine avec sa valeur de résolution ou d'échec.</p> + +<pre class="brush: js notranslate">const pErr = new Promise((resolve, reject) => { + reject("J'échoue toujours"); +}); + +const pLente = new Promise((resolve, reject) => { + setTimeout(resolve, 500, "Éventuellement résolue"); +}); + +const pRapide = new Promise((resolve, reject) => { + setTimeout(resolve, 100, "Rapidement résolue"); +}); + +Promise.any([pErr, pLente, pRapide]).then((valeur) => { + console.log(valeur); + // pRapide s'est résolue en premier +}); +// résultat attendu : "Rapidement résolue"</pre> + +<h3 id="Échec_avec_AggregateError">Échec avec AggregateError</h3> + +<p><code>Promise.any()</code> échoue avec un objet {{JSxRef("AggregateError")}} si aucun des promesses n'est résolue.</p> + +<pre class="brush: js notranslate">const pErr = new Promise((resolve, reject) => { + reject("J'échoue toujours"); +}); + +Promise.any([pErr]).catch((err) => { + console.log(err); +}) +// résultat attendu : "AggregateError: No Promise in Promise.any was resolved"</pre> + +<h3 id="Afficher_la_première_image_chargée">Afficher la première image chargée</h3> + +<p>Dans cet exemple, nous avons une fonction qui requête une image et retourne un Blob. Nous utilisons <code>Promise.any()</code> pour requêter plusieurs images et afficher la première qui nous sera disponible (c'est-à-dire dont la promesse sera résolue).</p> + +<pre class="brush: js notranslate">function fetchAndDecode(url) { + return fetch(url).then(réponse => { + if (!réponse.ok) + throw new Error(`Erreur HTTP ! état : ${response.status}`); + else + return réponse.blob(); + }) +} + +let café = fetchAndDecode('coffee.jpg'); +let thé = fetchAndDecode('tea.jpg'); + +Promise.any([café, thé]).then(valeur => { + let URLobjet = URL.createObjectURL(valeur); + let image = document.createElement('img'); + image.src = URLobjet; + document.body.appendChild(image); +}) +.catch(e => { + console.log(e.message); +});</pre> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <td><strong>Spécification</strong></td> + </tr> + <tr> + <td>{{SpecName('Promise.any')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + +<p>{{Compat("javascript.builtins.Promise.any")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li>{{JSxRef("Promise")}}</li> + <li>{{JSxRef("Promise.all()")}}</li> + <li>{{JSxRef("Promise.race()")}}</li> +</ul> diff --git a/files/fr/web/javascript/reference/global_objects/promise/catch/index.html b/files/fr/web/javascript/reference/global_objects/promise/catch/index.html new file mode 100644 index 0000000000..6fd60b4c6d --- /dev/null +++ b/files/fr/web/javascript/reference/global_objects/promise/catch/index.html @@ -0,0 +1,164 @@ +--- +title: Promise.prototype.catch() +slug: Web/JavaScript/Reference/Objets_globaux/Promise/catch +tags: + - ECMAScript 2015 + - JavaScript + - Méthode + - Promise + - Prototype + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/catch +--- +<div>{{JSRef}}</div> + +<p>La méthode <code><strong>catch()</strong></code> renvoie un objet {{jsxref("Promise")}} et ne traite que des cas où la promesse initiale est rejetée. Elle a le même effet qu'un appel à {{jsxref("Promise.then", "Promise.prototype.then(undefined, siRejetée)")}} (c'est en fait ce qui se passe dans le moteur, <code>obj.catch(onRejected)</code> est traduit en <code>obj.then(undefined, onRejected)</code>). Cela signifie qu'il est nécessaire de fournir une fonction <code>onRejected</code>, même si on souhaite avoir une valeur de secours qui est <code>undefined</code> (par exemple avec <code>obj.catch(() => {})</code>.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-catch.html")}}</div> + +<p class="hidden">Le code source de cet exemple interactif est disponible dans un dépôt GitHub. Si vous souhaitez contribuez à ces exemples, n'hésitez pas à cloner <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> et à envoyer une <em>pull request</em> !</p> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="syntaxbox"><var>p.catch(siRejetée)</var>; + +p.catch(function(raison) { + // rejet +}); +</pre> + +<h3 id="Paramètres">Paramètres</h3> + +<dl> + <dt><code>siRejetée</code></dt> + <dd>Une {{jsxref("Function","fonction","",1)}} à appeler si la <code>Promise</code> est rejetée (i.e. n'est pas tenue). Cette fonction possède un argument : + <dl> + <dt><code>raison</code></dt> + <dd>Une chaîne de caractères qui indique pourquoi la promesse n'est pas tenue.</dd> + </dl> + + <p>La promesse renvoyée par la méthode <code>catch()</code> est rompue si <code>siRejetée</code> lève une erreur ou si elle renvoie une promesse rompue. Dans les autres cas, elle est tenue.</p> + </dd> +</dl> + +<h3 id="Valeur_de_retour">Valeur de retour</h3> + +<p>Une promesse ({{jsxref("Promise")}}).</p> + +<h2 id="Description">Description</h2> + +<p>La méthode <code>catch()</code> est utile pour gérer les cas d'erreur en cas de compositions de plusieurs promesses. Elle renvoie elle-même une promesse et peut donc être utilisée lorsqu'on <a href="/fr/docs/Web/JavaScript/Guide/Utiliser_les_promesses#Chaînage_après_un_catch">chaîne des promesses</a>, à l'instar de la méthode sœur qu'est {{jsxref("Promise.prototype.then()")}}.</p> + +<h2 id="Exemples">Exemples</h2> + +<h3 id="Utilisation_de_la_méthode_catch">Utilisation de la méthode <code>catch</code></h3> + +<pre class="brush: js">var p1 = new Promise(function(resolve, reject) { + resolve("Succès"); +}); + +p1.then(function(value) { + console.log(value); // "Succès!" + throw new Error("zut !"); +}).catch(function(e) { + console.error(e.message); // "zut !" +}).then(function(e) { + console.log('après le catch, la chaîne est restaurée'); +}); + +// Le code qui suit est équivalent : +p1.then(function(value) { + console.log(value); // "Succès!" + return Promise.reject('zut !'); +}).catch(function(e) { + console.log(e); // "zut !" +}).then(function(e){ + console.log('après le catch, la chaîne est restaurée'); +}); +</pre> + +<h3 id="Les_promesses_n'interceptent_pas_les_exceptions_levées_de_façon_asynchrone">Les promesses n'interceptent pas les exceptions levées de façon asynchrone</h3> + +<pre class="brush: js">var p1 = new Promise(function(resolve, reject) { + throw new Error('Oh oh!'); +}); + +p1.catch(function(e) { + console.log(e.message); // "Oh oh!" +}); + +var p2 = new Promise(function(resolve, reject) { + setTimeout(function() { + throw new Error('Exception invisible !'); + }, 1000); +}); + +p2.catch(function(e) { + console.log(e.message); // Cela n'est jamais appelé +});</pre> + +<h3 id="Démonstration_de_l'appel_interne_à_then">Démonstration de l'appel interne à <code>then</code></h3> + +<pre class="brush: js">// On surcharge Promise.prototype.then/catch +// pour y ajouter des logs +(function(Promise){ + var originalThen = Promise.prototype.then; + var originalCatch = Promise.prototype.catch; + + Promise.prototype.then = function(){ + console.log('> > > > > > appel de .then sur %o avec les arguments: %o', this, arguments); + return originalThen.apply(this, arguments); + }; + Promise.prototype.catch = function(){ + console.log('> > > > > > appel de .catch sur %o avec les arguments: %o', this, arguments); + return originalCatch.apply(this, arguments); + }; + +})(this.Promise); + + + +// On appelle catch sur une promesse déjà résolue +Promise.resolve().catch(function XXX(){}); + +// Dans la console, on aura : +// > > > > > > appel de .catch sur Promise{} avec les arguments: Arguments{1} [0: function XXX()] +// > > > > > > appel de .then sur Promise{} avec les arguments: Arguments{2} [0: undefined, 1: function XXX()] +</pre> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Spécification</th> + <th scope="col">État</th> + <th scope="col">Commentaires</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ES2015', '#sec-promise.prototype.catch', 'Promise.prototype.catch')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Définition initiale au sein d'un standard ECMA.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.prototype.catch', 'Promise.prototype.catch')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + +<p class="hidden">Pour contribuer à ces données de compatibilité, vous pouvez envoyer une poule requête sur : <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p> + +<p>{{Compat("javascript.builtins.Promise.catch")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.prototype.then()")}}</li> +</ul> diff --git a/files/fr/web/javascript/reference/global_objects/promise/finally/index.html b/files/fr/web/javascript/reference/global_objects/promise/finally/index.html new file mode 100644 index 0000000000..b880bc4166 --- /dev/null +++ b/files/fr/web/javascript/reference/global_objects/promise/finally/index.html @@ -0,0 +1,106 @@ +--- +title: Promise.prototype.finally() +slug: Web/JavaScript/Reference/Objets_globaux/Promise/finally +tags: + - JavaScript + - Méthode + - Promises + - Reference + - finally +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/finally +--- +<div>{{JSRef}}</div> + +<p>La méthode <code><strong>finally()</strong></code> renvoie un objet <code>Promise</code> et accepte en argument une fonction de <em>callback</em> qui est appelée lorsque la promesse a été résolue (qu'elle ait été tenue ou rejetée). Cela permet d'exécuter du code une fois que la promesse a été traitée, quel que soit le résultat. On évite ainsi de dupliquer du code entre les gestionnaires {{jsxref("Promise.then", "then()")}} et {{jsxref("Promise.catch", "catch()")}}.</p> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="syntaxbox"><var>p.finally(onFinally)</var>; + +p.finally(function() { + // appelée dans tous les + // cas de terminaison +}); +</pre> + +<h3 id="Paramètres">Paramètres</h3> + +<dl> + <dt><code>onFinally</code></dt> + <dd>Une fonction (objet {{jsxref("Function")}}) appelé lorsque la promesse courante est résolue.</dd> +</dl> + +<h3 id="Valeur_de_retour">Valeur de retour</h3> + +<p>Cette méthode renvoie un objet {{jsxref("Promise")}}.</p> + +<h2 id="Description">Description</h2> + +<p>La méthode <code>finally</code> peut être utile si on souhaite effectuer un traitement ou du nettoyage (fermetures de flux, libération de ressources, etc.) une fois qu'une promesse est résolue, quel que soit l'état de la résolution (tenue ou rejetée).</p> + +<p>La méthode <code>finally</code> est similaire à l'utilisation de la forme <code>.then(onFinally, onFinally)</code>, on notera toutefois quelques différences :</p> + +<ul> + <li>Lorsqu'on crée une fonction en ligne, on peut ne la passer qu'une seule fois et éviter d'avoir à déclarer une variable ou à la déclarer à deux reprises.</li> + <li>Un <em>callback</em> <code>finally</code> ne recevra pas d'argument car on ne peut pas savoir si la promesse a été tenue ou rompue. Cette fonction est précisément appelée lorsqu'on ne s'intéresse pas à la raison du rejet ou à la réussite de la promesse. Une telle valeur est donc superflue. Ainsi : + <ul> + <li>À la différence de <code>Promise.resolve(2).then(() => {}, () => {})</code> qui sera résolue avec la valeur {{jsxref("undefined")}}, <code>Promise.resolve(2).finally(() => {})</code> sera résolue avec la valeur <code>2</code>.</li> + <li>De même, à la différence de <code>Promise.reject(3).then(() => {}, () => {})</code> qui sera résolue avec la valeur <code>undefined</code>, <code>Promise.reject(3).finally(() => {})</code> sera rejetée avec <code>3</code>.</li> + </ul> + </li> +</ul> + +<div class="note"> +<p><strong>Note :</strong> Toutefois, on notera qu'utiliser <code>throw</code> (ou que renvoyer une promesse rompue) dans le <em>callback</em> <code>finally</code> rejettera la promesse avec l'exception indiquée dans l'appel à <code>throw</code>.</p> +</div> + +<h2 id="Exemples">Exemples</h2> + +<pre class="brush: js">let isLoading = true; + +<code>fetch(myRequest).then(function(response) { + var contentType = response.headers.get("content-type"); + if(contentType && contentType.includes("application/json")) { + return response.json(); + } + throw new TypeError("Oups, ceci n'est pas du JSON !"); + }) + .then(function(json) { /* traiter le JSON */ }) + .catch(function(error) { console.log(error); + /* La ligne précédent peut aussi déclencher une + erreur (si console vaut {} par exemple) */ + }) +</code> .finally(function() { isLoading = false; }); + +</pre> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Spécification</th> + <th scope="col">État</th> + <th scope="col">Commentaires</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.prototype.finally', 'Promise.prototype.finally')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + +<div class="hidden">Ce tableau de compatibilité a été généré à partir de données structurées. Si vous souhaitez contribuer à ces données, n'hésitez pas à envoyer une <em>pull request</em> sur <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</div> + +<p>{{Compat("javascript.builtins.Promise.finally")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.prototype.then()")}}</li> + <li>{{jsxref("Promise.prototype.catch()")}}</li> +</ul> diff --git a/files/fr/web/javascript/reference/global_objects/promise/index.html b/files/fr/web/javascript/reference/global_objects/promise/index.html new file mode 100644 index 0000000000..36624cf3eb --- /dev/null +++ b/files/fr/web/javascript/reference/global_objects/promise/index.html @@ -0,0 +1,243 @@ +--- +title: Promise +slug: Web/JavaScript/Reference/Objets_globaux/Promise +tags: + - ECMAScript 2015 + - JavaScript + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise +--- +<div>{{JSRef}}</div> + +<p>L'objet <code><strong>Promise</strong></code> (pour « promesse ») est utilisé pour réaliser des traitements de façon asynchrone. Une promesse représente une valeur qui peut être disponible maintenant, dans le futur voire jamais.</p> + +<div class="note"> +<p><strong>Note :</strong> Cet article décrit le constructeur <code>Promise</code>. Pour en savoir plus sur les promesses en général, nous vous conseillons de lire l'article <a href="/fr/docs/Web/JavaScript/Guide/Utiliser_les_promesses">Utiliser les promesses</a>. Le constructeur <code>Promise</code> est principalement utilisé pour envelopper des fonctions qui ne prennent pas en charge les promesses.</p> +</div> + +<div>{{EmbedInteractiveExample("pages/js/promise-constructor.html")}}</div> + +<p class="hidden">Le code source de cet exemple interactif est disponible dans un dépôt GitHub. Si vous souhaitez contribuez à ces exemples, n'hésitez pas à cloner <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> et à envoyer une <em>pull request</em> !</p> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="syntaxbox">new Promise( /* exécuteur */ function(resolve, reject) { ... } );</pre> + +<h3 id="Paramètres">Paramètres</h3> + +<dl> + <dt><code>exécuteur</code></dt> + <dd>Une fonction à laquelle on passera deux arguments : <code>resolve</code> et <code>reject</code>. Cette fonction est exécutée immédiatement par l'implémentation de <strong><code>Promise</code></strong> qui fournit les fonctions <code>resolve</code> et <code>reject</code> (elle est exécutée avant que le constructeur <strong><code>Promise</code></strong> ait renvoyé l'objet créé). Les fonctions <code>resolve</code> et <code>reject</code>, lorsqu'elles sont appelées, permettent respectivement de tenir ou de rompre la promesse. On attend de l'exécuteur qu'il démarre un travail asynchrone puis, une fois le travail terminé, appelle la fonction <code>resolve</code> (si tout s'est bien passé) ou la fonction <code>reject</code> (lorsqu'il y a eu un problème) pour définir l'état final de la promesse.<br> + Si une erreur est générée par l'exécuteur, la promesse est rompue et la valeur de retour de l'exécuteur est ignorée.</dd> +</dl> + +<h2 id="Description">Description</h2> + +<p>L'interface <strong><code>Promise</code></strong> représente un intermédiaire (<em>proxy</em>) vers une valeur qui n'est pas nécessairement connue au moment de sa création. Cela permet d'associer des gestionnaires au succès éventuel d'une action asynchrone et à la raison d'une erreur. Ainsi, des méthodes asynchrones renvoient des valeurs comme les méthodes synchrones, la seule différence est que la valeur retournée par la méthode asynchrone est une promesse (d'avoir une valeur plus tard).</p> + +<p>Une <code>Promise</code> est dans un de ces états :</p> + +<ul> + <li><em>pending (en attente)</em> : état initial, la promesse n'est ni remplie, ni rompue ;</li> + <li><em>fulfilled (tenue</em>) : l'opération a réussi ;</li> + <li><em>rejected (rompue)</em> : l'opération a échoué ;</li> + <li><em>settled (acquittée)</em> : la promesse est tenue ou rompue mais elle n'est plus en attente.</li> +</ul> + +<p>Une promesse en attente peut être <em>tenue</em> avec une valeur ou <em>rompue</em> avec une raison (erreur). Quand on arrive à l'une des deux situations, les gestionnaires associés lors de l'appel de la méthode <code>then</code> sont alors appelés. (Si la promesse a déjà été tenue ou rompue lorsque le gestionnaire est attaché à la promesse, le gestionnaire est appelé. Cela permet qu'il n'y ait pas de situation de compétition entre une opération asynchrone en cours et les gestionnaires ajoutés).</p> + +<p>Les méthodes {{jsxref("Promise.then","Promise.prototype.then()")}} et {{jsxref("Promise.catch","Promise.prototype.catch()")}} renvoient des promesses et peuvent ainsi être chaînées. C'est ce qu'on appelle une <em>composition</em>.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/15911/promises.png" style="height: 297px; width: 801px;"></p> + +<div class="note"> +<p><strong>Note</strong>: Une promesse est dans l'état <em>settled </em>(acquittée) qu'elle soit tenue ou rompue mais plus en attente. Le terme <em>resolved</em> (résolue) est aussi utilisé concernant les promesses — cela signifie que la promesse est acquittée ou bien enfermée dans une chaine de promesse. Le billet de Domenic Denicola, <a href="https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md"><em>States and fates</em> (en anglais)</a>, contient de plus amples détails sur la terminologie utilisée.</p> +</div> + +<div class="warning"> +<p><strong>Attention :</strong> D'autres langages utilisent des mécanismes d'évaluation à la volée (<em>lazy evaluation</em>) et de déport des calculs (<em>deferring computations</em>). Ces mécanismes sont également intitulés promesses (<em>promises</em>). En JavaScript, les promesses correspondent à des processus déjà lancés et qui peuvent être chaînés avec des fonctions de retour. Si vous cherchez à retarder l'évaluation, vous pouvez utiliser les fonctions fléchées sans arguments (ex. <code>f = () => expression</code>) afin de créer une expression à évaluer plus tard et utiliser <code>f()</code> pour l'évaluer au moment voulu.</p> +</div> + +<h2 id="Propriétés">Propriétés</h2> + +<dl> + <dt><code>Promise.length</code></dt> + <dd>Une propriété de longueur qui vaut 1 (le nombre d'arguments pour le constructeur).</dd> + <dt>{{jsxref("Promise.prototype")}}</dt> + <dd>Cette propriété représente le prototype du constructeur <code>Promise</code>.</dd> +</dl> + +<h2 id="Méthodes">Méthodes</h2> + +<dl> + <dt>{{jsxref("Promise.all", "Promise.all(iterable)")}}</dt> + <dd>Renvoie une promesse tenue lorsque toutes les promesses de l'argument itérable sont tenues ou une promesse rompue dès qu'une promesse de l'argument itérable est rompue. Si la promesse est tenue, elle est résolue avec un tableau contenant les valeurs de résolution des différentes promesses contenues dans l'itérable (dans le même ordre que celui-ci). Si la promesse est rompue, elle contient la raison de la rupture de la part de la promesse en cause, contenue dans l'itérable. Cette méthode est utile pour agréger les résultats de plusieurs promesses tous ensemble.</dd> + <dt>{{jsxref("Promise.allSettled", "Promise.allSettled(iterable)")}}</dt> + <dd>Attend que l'ensemble des promesses aient été acquittées (tenues ou rompues) et renvoie une promesse qui est résolue après que chaque promesse ait été tenue ou rompue. La valeur de résolution de la promesse renvoyée est un tableau dont chaque élément est le résultat des promesses initiales.</dd> + <dt>{{jsxref("Promise.race", "Promise.race(iterable)")}}</dt> + <dd>Renvoie une promesse qui est tenue ou rompue dès que l'une des promesses de l'itérable est tenue ou rompue avec la valeur ou la raison correspondante.</dd> +</dl> + +<dl> + <dt>{{jsxref("Promise.reject", "Promise.reject(raison)")}}</dt> + <dd>Renvoie un objet <code>Promise</code> qui est rompue avec la raison donnée.</dd> +</dl> + +<dl> + <dt>{{jsxref("Promise.resolve", "Promise.resolve(valeur)")}}</dt> + <dd>Renvoie un objet <code>Promise</code> qui est tenue (résolue) avec la valeur donnée. Si la valeur possède une méthode <code>then</code>, la promesse renvoyée « suivra » cette méthode pour arriver dans son état, sinon la promesse renvoyée sera tenue avec la valeur fournie. Généralement, quand on veut savoir si une valeur est une promesse, on utilisera {{jsxref("Promise.resolve","Promise.resolve(valeur)")}} et on travaillera avec la valeur de retour en tant que promesse.</dd> +</dl> + +<h2 id="Prototype_pour_Promise">Prototype pour <code>Promise</code></h2> + +<h3 id="Propriétés_2">Propriétés</h3> + +<p>{{page('fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise/prototype','Propriétés')}}</p> + +<h3 id="Méthodes_2">Méthodes</h3> + +<p>{{page('fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise/prototype','Méthodes')}}</p> + +<h2 id="Exemples">Exemples</h2> + +<h3 id="Créer_une_promesse">Créer une promesse</h3> + +<p>Pour créer une promesse, on utilise l'opérateur <code>new</code> et le constructeur. Celui-ci prend en argument une fonction qui prend deux fonctions en paramètres. La première est appelée quand la tâche asynchrone est correctement terminée et la seconde est appelée quand la tâche échoue :</p> + +<pre class="brush: js">const maPremierePromesse = new Promise((resolve, reject) => { + // réaliser une tâche asynchrone et appeler : + + // resolve(uneValeur); // si la promesse est tenue + // ou + // reject("raison d'echec"); // si elle est rompue +}); +</pre> + +<p>On peut ainsi obtenir des fonctions asynchrones en renvoyant une promesse :</p> + +<pre class="brush: js">function maFonctionAsynchrone(url) { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open("GET", url); + xhr.onload = () => resolve(xhr.responseText); + xhr.onerror = () => reject(xhr.statusText); + xhr.send(); + }); +}</pre> + +<h3 id="Exemple_interactif">Exemple interactif</h3> + +<pre class="brush: html hidden"><button id="btn" type="button">Créer un objet Promise !</button> +<div id="log"></div> +</pre> + +<p>Dans le court exemple qui suit, on illustre le mécanisme d'une <code>Promise</code>. La méthode <code>testPromise()</code> est appelée chaque fois qu'on clique sur l'élément {{HTMLElement("button")}}. Cette méthode crée une promesse qui sera tenue grâce à la fonction {{domxref("window.setTimeout()")}}, et avec la valeur comptePromesse (nombre commançant à 1) après <code>1s</code> à <code>3s</code> (aléatoire). Le constructeur Promise() est utilisé pour créer la promesse.</p> + +<p>Le fait que la promesse soit tenue est simplement enregistré via un <em>callback</em> sur <code>p1.then()</code>. Quelques indicateurs illustrent la manière dont la partie synchrone est découplée de la partie asynchrone.</p> + +<pre class="brush: js">'use strict'; +var comptePromesse = 0; + +function testPromise() { + var thisComptePromesse = ++comptePromesse; + + var log = document.getElementById('log'); + log.insertAdjacentHTML('beforeend', thisComptePromesse + + ') Started (<small>Début du code synchrone</small>)<br/>'); + + // on crée une nouvelle promesse : + var p1 = new Promise( + // La fonction de résolution est appelée avec la capacité de + // tenir ou de rompre la promesse + function(resolve, reject) { + log.insertAdjacentHTML('beforeend', thisComptePromesse + + ') Promise started (<small>Début du code asynchrone</small>)<br/>'); + + // Voici un exemple simple pour créer un code asynchrone + window.setTimeout( + function() { + // On tient la promesse ! + resolve(thisComptePromesse); + }, Math.random() * 2000 + 1000); + }); + + // On définit ce qui se passe quand la promesse est tenue + // et ce qu'on appelle (uniquement) dans ce cas + // La méthode catch() définit le traitement à effectuer + // quand la promesse est rompue. + p1.then( + // On affiche un message avec la valeur + function(val) { + log.insertAdjacentHTML('beforeend', val + + ') Promise fulfilled (<small>Fin du code asynchrone</small>)<br/>'); + }).catch( + // Promesse rejetée + function() { + console.log("promesse rompue"); + }); + + log.insertAdjacentHTML('beforeend', thisComptePromesse + + ') Promise made (<small>Fin du code synchrone</small>)<br/>'); +} +</pre> + +<pre class="brush: js hidden">if ("Promise" in window) { + var btn = document.getElementById("btn"); + btn.addEventListener("click", testPromise); + } else { + log = document.getElementById('log'); + log.innerHTML = "L'exemple live n'est pas disponible pour votre navigateur car celui-ci ne supporte pas l'interface <code>Promise<code>."; +}</pre> + +<p>L'exemple s'exécute lorsqu'on clique sur le bouton. Pour tester cet exemple, il est nécessaire d'utiliser un navigateur qui supporte les objets <code>Promise</code>. En cliquant plusieurs fois sur le bouton en peu de temps, on verra qu'il y a plusieurs promesses tenues les une après les autres.</p> + +<p>{{EmbedLiveSample('Exemple_interactif', '500', '200')}}</p> + +<h2 id="Charger_une_image_en_XHR">Charger une image en XHR</h2> + +<p>Un autre exemple simple utilisant <code>Promise</code> et {{domxref("XMLHttpRequest")}} afin de charger une image est disponible sur le dépôt GitHub MDN <a href="https://github.com/mdn/js-examples/tree/master/promises-test">js-examples</a>. Vous pouvez également <a href="https://mdn.github.io/js-examples/promises-test/">voir le résultat</a>. Chaque étape est commentée afin de vous permettre de suivre l'état de la promesse et l'architecture utilisée avec XHR.</p> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Spécification</th> + <th scope="col">État</th> + <th scope="col">Commentaires</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-promise-objects', 'Promise')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Définition initiale au sein d'un standard ECMA.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise-objects', 'Promise')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + +<p class="hidden">Pour contribuer à ces données de compatibilité, vous pouvez envoyer une poule requête sur : <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p> + +<p>{{Compat("javascript.builtins.Promise")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li><a href="/fr/docs/Web/JavaScript/Guide/Utiliser_les_promesses">Manipuler les promesses</a></li> + <li><a href="https://promisesaplus.com/">Promises/A+ specification</a></li> + <li><a href="https://medium.com/@ramsunvtech/promises-of-promise-part-1-53f769245a53">Venkatraman.R - JS Promise (Part 1, Basics) </a>(en anglais)</li> + <li><a href="https://medium.com/@ramsunvtech/js-promise-part-2-q-js-when-js-and-rsvp-js-af596232525c#.dzlqh6ski">Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js) </a>(en anglais)</li> + <li><a href="https://tech.io/playgrounds/11107/tools-for-promises-unittesting/introduction">Venkatraman.R - Tools for Promises Unit Testing </a>(en anglais)</li> + <li><a href="https://www.html5rocks.com/en/tutorials/es6/promises/">Jake Archibald : <em>JavaScript Promises : There and Back Again</em></a> (tutoriel en anglais)</li> + <li><a href="https://de.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript">Domenic Denicola : <em>Callbacks, Promises, and Coroutines – Asynchronous Programming Patterns in JavaScript</em></a> (présentation en anglais sur l'asynchronisme en JavaScript)</li> + <li><a href="https://www.mattgreer.org/articles/promises-in-wicked-detail/">Matt Greer : <em>JavaScript Promises ... In Wicked Detail</em></a> (en anglais)</li> + <li><a href="https://www.promisejs.org/">Forbes Lindesay : promisejs.org</a> (en anglais)</li> + <li><a href="https://github.com/jakearchibald/es6-promise/">Prothèse pour les promesses par Jake Archibald</a></li> + <li><a href="https://www.udacity.com/course/javascript-promises--ud898">Les promesses JavaScript sur Udacity</a> (en anglais)</li> +</ul> diff --git a/files/fr/web/javascript/reference/global_objects/promise/race/index.html b/files/fr/web/javascript/reference/global_objects/promise/race/index.html new file mode 100644 index 0000000000..afb407d7db --- /dev/null +++ b/files/fr/web/javascript/reference/global_objects/promise/race/index.html @@ -0,0 +1,191 @@ +--- +title: Promise.race() +slug: Web/JavaScript/Reference/Objets_globaux/Promise/race +tags: + - ECMAScript 2015 + - JavaScript + - Méthode + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/race +--- +<div>{{JSRef}}</div> + +<p>La méthode <code><strong>Promise.race()</strong></code> renvoie une promesse qui est résolue ou rejetée dès qu'une des promesses de l'itérable passé en argument est résolue ou rejetée. La valeur (dans le cas de la résolution) ou la raison (dans le cas d'un échec) utilisée est celle de la promesse de l'itérable qui est resolue/qui échoue.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-race.html")}}</div> + +<p class="hidden">Le code source de cet exemple interactif est disponible dans un dépôt GitHub. Si vous souhaitez contribuez à ces exemples, n'hésitez pas à cloner <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> et à envoyer une <em>pull request</em> !</p> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="syntaxbox">Promise.race(<var>itérable</var>);</pre> + +<h3 id="Paramètres">Paramètres</h3> + +<dl> + <dt><code>itérable</code></dt> + <dd>Un objet itérable, par exemple un {{jsxref("Array")}}. Voir la page <a href="/fr/docs/Web/JavaScript/Guide/iterable">itérable</a>.</dd> +</dl> + +<h3 id="Valeur_de_retour">Valeur de retour</h3> + +<p>Une promesse ({{jsxref("Promise")}}) à résoudre qui est résolue de façon asynchrone dès que l'une des promesses de l'itérable est tenue ou rompue.</p> + +<h2 id="Description">Description</h2> + +<p>La fonction <code>race</code> renvoie une <code>Promise</code> qui est résolue/rejetée de la même façon que la première promesse de l'itérable à être résolue/rejetée.</p> + +<p>Si l'itérable passé en argument est vide, la promesse sera continuellement en attente.</p> + +<p>Si l'itérable contient une ou plusieurs valeurs qui ne sont pas des promesses ou une promesse déjà résolue, <code>Promise.race</code> fournira une promesse résolue avec la première de ces valeurs trouvées dans l'itérable.</p> + +<h2 id="Exemples">Exemples</h2> + +<h3 id="Caractère_asynchrone_de_Promise.race()">Caractère asynchrone de <code>Promise.race()</code></h3> + +<p>L'exemple qui suit illuste le caractère asynchrone de <code>Promise.race:</code></p> + +<pre class="brush: js">// On passe un tableau de promesses déjà résolues +// en argument afin de déclencher Promise.race +// dès que possible +var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)]; + +var p = Promise.race(resolvedPromisesArray); +// On affiche immédiatement la valeur p dans la console +console.log(p); + +// Avec setTimeout on peut exécuter du code +// une fois que la pile est vide +setTimeout(function(){ + console.log('La pile est désormais vide'); + console.log(p); +}); + +// affichera, dans cet ordre : +// Promise { <state>: "pending" } +// La pile est désormais vide +// Promise { <state>: "fulfilled", <value>: 33 }</pre> + +<p>Un itérable vide renverra une promesse qui restera en attente :</p> + +<pre class="brush: js">var foreverPendingPromise = Promise.race([]); +console.log(foreverPendingPromise); +setTimeout(function(){ + console.log('La pile est désormais vide'); + console.log(foreverPendingPromise); +}); + +// affichera, dans cet ordre : +// Promise { <state>: "pending" } +// La pile est désormais vide +// Promise { <state>: "pending" } +</pre> + +<p>Si l'itérable contient une ou plusieurs valeurs qui ne sont pas des promesses ou des promesses déjà résolues, <code>Promise.race</code> considèrera la première valeur ainsi trouvée dans l'itérable :</p> + +<pre class="brush: js">var foreverPendingPromise = Promise.race([]); +var alreadyResolvedProm = Promise.resolve(666); + +var arr = [foreverPendingPromise, alreadyResolvedProm, "non-Promise value"]; +var arr2 = [foreverPendingPromise, "non-Promise value", Promise.resolve(666)]; +var p = Promise.race(arr); +var p2 = Promise.race(arr2); + +console.log(p); +console.log(p2); +setTimeout(function(){ + console.log('the stack is now empty'); + console.log(p); + console.log(p2); +}); + +// affichera dans l'ordre : +// Promise { <state>: "pending" } +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "fulfilled", <value>: 666 } +// Promise { <state>: "fulfilled", <value>: "non-Promise value" } +</pre> + +<h3 id="Utilisation_de_Promise.race_–_exemples_avec_setTimeout">Utilisation de <code>Promise.race</code> – exemples avec <code>setTimeout</code></h3> + +<pre class="brush: js">var p1 = new Promise(function(resolve, reject) { + setTimeout(resolve, 500, "un"); +}); +var p2 = new Promise(function(resolve, reject) { + setTimeout(resolve, 100, "deux"); +}); + +Promise.race([p1, p2]).then(function(value) { + console.log(value); // "deux" + // Les deux promesses sont résolues mais p2 est plus rapide +}); + +var p3 = new Promise(function(resolve, reject) { + setTimeout(resolve, 100, "trois"); +}); +var p4 = new Promise(function(resolve, reject) { + setTimeout(reject, 500, "quatre"); +}); + +Promise.race([p3, p4]).then(function(value) { + console.log(value); // "trois" + // p3 est plus rapide et entraîne la résolution de la promesse de compétition +}, function(reason) { + // N'est pas appelée +}); + +var p5 = new Promise(function(resolve, reject) { + setTimeout(resolve, 500, "cinq"); +}); +var p6 = new Promise(function(resolve, reject) { + setTimeout(reject, 100, "six"); +}); + +Promise.race([p5, p6]).then(function(value) { + // N'est pas appelée +}, function(reason) { + console.log(reason); // "six" + // p6 est plus rapide et rejète la promesse de compétition +}); +</pre> + +<div class="note"> +<p><strong>Note :</strong> voir la documentation sur <a href="/fr/docs/Web/API/WindowTimers/setTimeout"><code>setTimeout</code>.</a></p> +</div> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Spécification</th> + <th scope="col">État</th> + <th scope="col">Commentaires</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-promise.race', 'Promise.race')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Définition initiale au sein d'un standard ECMA.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.race', 'Promise.race')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + +<p class="hidden">Pour contribuer à ces données de compatibilité, vous pouvez envoyer une poule requête sur : <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("javascript.builtins.Promise.race")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.all()")}}</li> +</ul> diff --git a/files/fr/web/javascript/reference/global_objects/promise/reject/index.html b/files/fr/web/javascript/reference/global_objects/promise/reject/index.html new file mode 100644 index 0000000000..d792a2eaa4 --- /dev/null +++ b/files/fr/web/javascript/reference/global_objects/promise/reject/index.html @@ -0,0 +1,79 @@ +--- +title: Promise.reject() +slug: Web/JavaScript/Reference/Objets_globaux/Promise/reject +tags: + - ECMAScript 2015 + - JavaScript + - Méthode + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/reject +--- +<div>{{JSRef}}</div> + +<p>La méthode <code><strong>Promise.reject(raison)</strong></code> renvoie un objet <code>Promise</code> qui est rejeté (la promesse n'est pas tenue) à cause d'une raison donnée.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-reject.html")}}</div> + +<p class="hidden">Le code source de cet exemple interactif est disponible dans un dépôt GitHub. Si vous souhaitez contribuez à ces exemples, n'hésitez pas à cloner <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> et à envoyer une <em>pull request</em> !</p> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="syntaxbox">Promise.reject(<var>raison</var>);</pre> + +<h3 id="Paramètres">Paramètres</h3> + +<dl> + <dt><code>raison</code></dt> + <dd>La raison pour laquelle la <code>Promise</code> n'a pas été tenue.</dd> +</dl> + +<h3 id="Valeur_de_retour">Valeur de retour</h3> + +<p>Une promesse ({{jsxref("Promise")}}) qui est rompue avec la raison passée en argument.</p> + +<h2 id="Description">Description</h2> + +<p>La fonction statique <code>Promise.reject</code> renvoie une <code>Promise</code> qui est rejetée. Pour faciliter le débogage (comprendre plus rapidement le problème et sélectionner une erreur précise), il peut être utile que l'argument <code>raison</code> soit une instance d'{{jsxref("Error")}}.</p> + +<h2 id="Exemples">Exemples</h2> + +<pre class="brush: js">Promise.reject(new Error("échec")).then(function() { + // n'est pas appelée +}, function(erreur) { + console.log(erreur); // Analyse de la pile d'appels +});</pre> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Spécification</th> + <th scope="col">État</th> + <th scope="col">Commentaires</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-promise.reject', 'Promise.reject')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Définition initiale au sein d'un standard ECMA.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.reject', 'Promise.reject')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + +<p class="hidden">Pour contribuer à ces données de compatibilité, vous pouvez envoyer une poule requête sur : <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p> + +<p>{{Compat("javascript.builtins.Promise.reject")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> +</ul> diff --git a/files/fr/web/javascript/reference/global_objects/promise/resolve/index.html b/files/fr/web/javascript/reference/global_objects/promise/resolve/index.html new file mode 100644 index 0000000000..abda218c20 --- /dev/null +++ b/files/fr/web/javascript/reference/global_objects/promise/resolve/index.html @@ -0,0 +1,156 @@ +--- +title: Promise.resolve() +slug: Web/JavaScript/Reference/Objets_globaux/Promise/resolve +tags: + - ECMAScript 2015 + - JavaScript + - Méthode + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/resolve +--- +<div>{{JSRef}}</div> + +<p>La méthode <code><strong>Promise.resolve(valeur)</strong></code> renvoie un objet {{jsxref("Promise")}} qui est résolu avec la valeur donnée. Si cette valeur est une promesse, la promesse est renvoyée, si la valeur possède une méthode {{jsxref("Promise.then","then")}}, la promesse renvoyée « suivra » cette méthode et prendra son état ; sinon, la promesse renvoyée sera tenue avec la valeur.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-resolve.html")}}</div> + +<p class="hidden">Le code source de cet exemple interactif est disponible dans un dépôt GitHub. Si vous souhaitez contribuez à ces exemples, n'hésitez pas à cloner <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> et à envoyer une <em>pull request</em> !</p> + +<div class="blockIndicator warning"> +<p><strong>Attention !</strong> <code>Promise.resolve()</code> ne doit pas être appelée sur un objet <em>thenable</em> qui se résout en lui-même. Cela provoquera une récursion infinie et <code>resolve()</code> tentera d'aplatir ce qui ressemble à une promesse imbriquée à l'infini.</p> +</div> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="syntaxbox"><var>Promise.resolve(valeur)</var>; +Promise.resolve(promesse); +Promise.resolve(suivant); +</pre> + +<h3 id="Paramètres">Paramètres</h3> + +<dl> + <dt><code>valeur</code></dt> + <dd>L'argument qu'on souhaite résoudre avec cette promesse (<code>Promise</code>). Cet argument peut être un objet <code>Promise</code> ou un objet avec une méthode <code>then</code> à résoudre à la suite.</dd> +</dl> + +<h3 id="Valeur_de_retour">Valeur de retour</h3> + +<p>Une promesse ({{jsxref("Promise")}}) qui est résolue avec la valeur indiquée en argument ou la promesse passée en argument si celui-ci est une promesse.</p> + +<h2 id="Description">Description</h2> + +<p>La fonction statique <code>Promise.resolve</code> renvoie un objet <code>Promise</code> qui est résolu.</p> + +<h2 id="Exemples">Exemples</h2> + +<h3 id="Utilisation_de_la_méthode_statique_Promise.resolve">Utilisation de la méthode statique <code>Promise.resolve</code></h3> + +<pre class="brush: js">Promise.resolve("Succès").then(function(valeur) { + console.log(valeur); // "Succès" +}, function(valeur) { + // n'est pas appelée +}); +</pre> + +<h3 id="Résoudre_un_tableau">Résoudre un tableau</h3> + +<pre class="brush: js">var p = Promise.resolve([1,2,3]); +p.then(function(v) { + console.log(v[0]); // 1 +}); +</pre> + +<h3 id="Résoudre_une_autre_Promise">Résoudre une autre <code>Promise</code></h3> + +<pre class="brush: js">var original = Promise.resolve(33); +var cast = Promise.resolve(original); +cast.then(function(value) { + console.log("value: " + value); +}); +console.log("original === cast ? " + (original === cast)); + +// affiche ceci dans la console (dans cet ordre) : +// original === cast ? true +// value: 33 +</pre> + +<p>L'ordre des traces dans la console est dû au fait que les gestionnaires <code>then()</code> sont appelés de façon asynchrone (plus de détails sur <code>then</code> <a href="/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise/then#Valeur_de_retour">dans cet article</a>).</p> + +<h3 id="Résoudre_des_objets_avec_then_et_renvoyer_des_erreurs">Résoudre des objets avec <code>then</code> et renvoyer des erreurs</h3> + +<pre class="brush: js">// Résoudre un objet avec then +var p1 = Promise.resolve({ + then: function(onFulfill, onReject) { onFulfill("tenue !"); } +}); +console.log(p1 instanceof Promise) // true, l'objet est transformée en une Promise + +p1.then(function(v) { + console.log(v); // "tenue !" + }, function(e) { + // n'est pas appelée +}); + +// L'objet avec then renvoie une erreur avant le callback +// La promesse n'est pas tenue +var thenable = { then: function(resolve) { + throw new TypeError("Renvoi d'erreur"); + resolve("Résolution "); +}}; + +var p2 = Promise.resolve(thenable); +p2.then(function(v) { + // n'est pas appelée +}, function(e) { + console.log(e); // TypeError : Renvoi d'erreur +}); + +// L'objet avec then renvoie une erreur après le callback +// La promesse est tenue +var thenable = { then: function(resolve) { + resolve("Résolue"); + throw new TypeError("Erreur"); +}}; + +var p3 = Promise.resolve(thenable); +p3.then(function(v) { + console.log(v); // "Résolue" +}, function(e) { + // n'est pas appelée +}); +</pre> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Spécification</th> + <th scope="col">État</th> + <th scope="col">Commentaires</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-promise.reject', 'Promise.reject')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Définition initiale au sein d'un standard ECMA.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.resolve', 'Promise.resolve')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + +<p class="hidden">Pour contribuer à ces données de compatibilité, vous pouvez envoyer une poule requête sur : <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p> + +<p>{{Compat("javascript.builtins.Promise.resolve")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> +</ul> diff --git a/files/fr/web/javascript/reference/global_objects/promise/then/index.html b/files/fr/web/javascript/reference/global_objects/promise/then/index.html new file mode 100644 index 0000000000..b077425e5a --- /dev/null +++ b/files/fr/web/javascript/reference/global_objects/promise/then/index.html @@ -0,0 +1,265 @@ +--- +title: Promise.prototype.then() +slug: Web/JavaScript/Reference/Objets_globaux/Promise/then +tags: + - ECMAScript6 + - JavaScript + - Méthode + - Promise + - Prototype + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/then +--- +<div>{{JSRef}}</div> + +<p>La méthode <code><strong>then()</strong></code> renvoie un objet {{jsxref("Promise")}}. Elle peut prendre jusqu'à deux arguments qui sont deux fonctions <em>callback</em> à utiliser en cas de complétion ou d'échec de la <code>Promise</code>.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-then.html")}}</div> + +<p class="hidden">Le code source de cet exemple interactif est disponible dans un dépôt GitHub. Si vous souhaitez contribuez à ces exemples, n'hésitez pas à cloner <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> et à envoyer une <em>pull request</em> !</p> + +<div class="note"> +<p><strong>Note :</strong> Si aucun des deux arguments n'est utilisé ou que les objets fournis ne sont pas des fonctions, une nouvelle promesse est créée sans autre gestionnaire supplémentaire. Si le premier argument est absent ou qu'un objet qui n'est pas une fonction est passé, la nouvelle promesse utilisera la fonction de réussite de la promesse originelle. De même, si le deuxième argument n'est pas passé ou que ce n'est pas une fonction, la nouvelle promesse créée utilisera la fonction de rejet de la promesse appelante.</p> +</div> + +<h2 id="Syntaxe">Syntaxe</h2> + +<pre class="syntaxbox"><var>p.then(siTenue); +p.then(siTenue, siRejetée)</var>; + +p.then((valeur) => { + // Promesse tenue + }, (raison) => { + // Rejet de la promesse +}); +</pre> + +<h3 id="Paramètres">Paramètres</h3> + +<ul> +</ul> + +<dl> + <dt><code>siTenue</code></dt> + <dd>Une {{jsxref("Function","fonction","",1)}} appelée lorsque la <code>Promise</code> est tenue. Cette fonction a un seul argument, la <code>valeur</code> qui a permis de résoudre la promesse. Si <code>siTenue</code> n'est pas une fonction, elle est implicitement remplacée par une fonction « identité » qui renvoie l'argument tel quel.</dd> + <dt><code>siRejetée</code> {{optional_inline}}</dt> + <dd>Une {{jsxref("Function","fonction","",1)}} appelée lorsque la <code>Promise</code> est rejetée. Cette fonction a un seul argument, la <code>raison</code> pour laquelle la promesse a été rejetée. Si <code>siRejetée</code> n'est pas une fonction, elle est implicitement remplacée par une fonction qui lève une erreur avec la <code>raison</code> passée en argument.</dd> +</dl> + +<h3 id="Valeur_de_retour">Valeur de retour</h3> + +<p>La méthode <code>then()</code> renvoie une promesse ({{jsxref("Promise")}}) en attente de résolution et dont la valeur est déterminée selon les deux fonctions passées en arguments et qui seront appelées de façon asynchrone :</p> + +<ul> + <li>Si <code>siRejetée</code> ou <code>siTenue</code> lève une exception ou renvoie une promesse rompue, la promesse renvoyée par <code>then()</code> est rompue et la valeur fournie est l'exception ou l'explication de la promesse rompue.</li> + <li>Si <code>siRejetée</code> ou <code>siTenue</code> renvoie une promesse tenue ou n'importe quelle autre valeur, la promesse renvoyée est tenue et la valeur de résolution est la même que celle de la promesse tenue.</li> + <li>Si <code>siRejetée</code> ou <code>siTenue</code> renvoie une promesse en attente de résolution, la promesse renvoyée par <code>then()</code> sera résolue de la même façon que la promesse renvoyée par le gestionnaire. En fait, dans ce cas, la promesse renvoyée par <code>then()</code> est la même que la promesse renvoyée par le gestionnaire (<code>siTenue</code> ou <code>siRejetée</code>).</li> +</ul> + +<h2 id="Description">Description</h2> + +<p>Comme les méthodes <code>then()</code> et {{jsxref("Promise.prototype.catch()")}} renvoient des promesses, on peut enchaîner ces opérations (c'est ce qu'on appelle la <em>composition</em> de promesses, voir l'exemple ci-après).</p> + +<h2 id="Exemples">Exemples</h2> + +<h3 id="Utilisation_de_la_méthode_then()">Utilisation de la méthode <code>then()</code></h3> + +<pre class="brush: js">var p1 = new Promise(function(resolve, reject) { + resolve("Succès !"); + // ou + // reject("Erreur !"); +}); + +p1.then((valeur) => { + console.log(valeur); // Succès ! + }, (raison) => { + console.log(raison); // Erreur ! +}); +</pre> + +<h3 id="Composition_-_Chaînage">Composition - Chaînage</h3> + +<p>La méthode <code>then()</code> renvoie un objet <code>Promise</code>, ce qui permet d'enchaîner les opération. On peut passer une fonction lambda à then puis utiliser la promesse obtenue pour la passer à la méthode suivante. Dans l'exemple ci-après, on simule un code asynchrone avec la fonction <code>setTimeout</code>.</p> + +<pre class="brush: js">Promise.resolve("toto") + // 1. Première étape, on reçoit "toto" et on le concatène avec + // "truc", ce qui résoud la première étape puis on passe au + // deuxième then + .then(function(string) { + return new Promise(function(resolve, reject) { + setTimeout(function() { + string += 'truc'; + resolve(string); + }, 1); + }); + }) + // 2. Deuxième étape, on reçoit "tototruc" et on enregistre une + // fonction de rappel pour manipuler cette chaîne puis l'imprimer + // dans la console. Avant cela, on passe la chaîne intacte au + // prochain then + .then(function(string) { + setTimeout(function() { + string += 'baz'; + console.log(string); + }, 1) + return string; + }) + // 3. On affiche un message sur le code, celui-ci sera affiché + // avant que la chaîne soit traitée dans le bloc précédent + // qui agit comme un bloc asynchrone. + .then(function(string) { + console.log("Et voilà la dernière, qui risque d'arriver avant la 2e"); + + // Ici, la chaîne n'aura pas le morceau 'baz' car la fonction + // setTimeout retarde l'exécution du code. + console.log(string); +}); +</pre> + +<p>Lorsqu'une valeur est simplement renvoyée depuis une fonction lambda <code>then</code>, celle-ci renverra <code>Promise.resolve(<la valeur renvoyée par le gestionnaire appelé>)</code>.</p> + +<pre class="brush: js">var p2 = new Promise(function(resolve, reject) { + resolve(1); +}); + +p2.then(function(valeur) { + console.log(valeur); // 1 + return valeur + 1; + }).then(function(valeur) { + console.log(valeur + "- cette utilisation synchrone est un peu inutile"); + // 2- cette utilisation synchrone est un peu inutile +}); + +p2.then(function(valeur) { + console.log(valeur); // 1 +}); +</pre> + +<p>Appeler <code>then()</code> renverra une promesse rompue si la fonction lève une exception ou si elle renvoie une promesse rompue.</p> + +<pre class="brush: js">Promise.resolve() + .then( () => { + // Ici .then() lève une exception + throw 'Oh zut :( !'; + }) + .then( () => { + console.log( "Ceci n'est pas appelé." ); + }, raison => { + console.error( 'la fonction siRompue est appelée : ' + raison ); +});</pre> + +<p>Dans tous les autres cas, un promesse de résolution est renvoyée. Dans l'exemple qui suit, le premier <code>then()</code> renvoie <code>42</code> même si la promesse précédente a été rompue :</p> + +<pre class="brush: js">Promise.reject() + .then( () => 99, () => 42 ) // la valeur 42 est renvoyée dans une promesse + .then( solution => console.log( 'Résolue avec ' + solution ) ); // Résolue avec 42</pre> + +<p>En pratique, il est souvent préférable d'attraper les promesses rompues plutôt que d'utiliser la syntaxe de <code>then()</code> avec deux fonctions :</p> + +<pre class="brush: js">Promise.resolve() + .then( () => { + // .then() renvoie une promesse rompue + throw 'Oh zut !'; + }) + .catch( raison => { + console.error( 'fonction siRompue appelée : ' + raison ); + }) + .then( () => { + console.log("Je suis toujours appelée, même si il y a un souci avant"); + });</pre> + +<p>Le chaînage peut également être utilisé pour implémenter une fonction utilisant une API basée sur les promesses et encapsuler une autre fonction :</p> + +<pre class="brush: js">function fetch_current_data() { + // L'API fetch renvoie une promesse. Cette fonction + // expose une API similaire mais lorsque la promesse + // est tenue, on effectue plus de tâches + return fetch("current-data.json").then((response) => { + if (response.headers.get("content-type") != "application/json") { + throw new TypeError(); + } + var j = response.json(); + // on peut ici manipuler j si besoin + return j; // la valeur fournie à l'utilisateur de + // fetch_current_data().then() + }); +} +</pre> + +<p>Si le gestionnaire <code><em>siTenue</em></code> renvoie une promesse, la valeur de retour de <code>then()</code> sera alors résolue/rompue par cette promesse.</p> + +<pre class="brush: js">function resoudrePlusTard(resolve, reject) { + setTimeout(function () { + resolve(10); + }, 1000); +} +function romprePlusTard(resolve, reject) { + setTimeout(function () { + reject(20); + }, 1000); +} + +var p1 = Promise.resolve("toto"); +var p2 = p1.then(function() { + // On renvoie une nouvelle promesse + // qui sera résolue avec la valeur 10 + // au bout d'une seconde + return new Promise(resoudrePlusTard); +}); +p2.then(function(v) { + console.log("tenue", v); + // "tenue", 10 +}, function(e) { + // ceci n'est pas appelé + console.log("rompue", e); +}); + +var p3 = p1.then(function() { + // Ici, on renvoie une promesse + // qui sera rompue avec la valeur + // 20 au bout d'une seconde + return new Promise(romprePlusTard); +}); +p3.then(function(v) { + // ceci n'est pas appelé + console.log("tenue", v); +}, function(e) { + console.log("rompue", e); + // "rompue", 20 +}); +</pre> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Spécification</th> + <th scope="col">État</th> + <th scope="col">Commentaires</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-promise.prototype.then', 'Promise.prototype.then')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Définition initiale au sein d'un standard ECMA.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.prototype.then', 'Promise.prototype.then')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2> + +<p class="hidden">Pour contribuer à ces données de compatibilité, vous pouvez envoyer une poule requête sur : <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p> + +<p>{{Compat("javascript.builtins.Promise.then")}}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.prototype.catch()")}}</li> +</ul> |