--- title: Promise slug: Web/JavaScript/Reference/Global_Objects/Promise tags: - ECMAScript 2015 - JavaScript - Promise - Reference translation_of: Web/JavaScript/Reference/Global_Objects/Promise original_slug: Web/JavaScript/Reference/Objets_globaux/Promise ---
L'objet Promise
(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.
Note : Cet article décrit le constructeur Promise
. Pour en savoir plus sur les promesses en général, nous vous conseillons de lire l'article Utiliser les promesses. Le constructeur Promise
est principalement utilisé pour envelopper des fonctions qui ne prennent pas en charge les promesses.
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 https://github.com/mdn/interactive-examples et à envoyer une pull request !
new Promise( /* exécuteur */ function(resolve, reject) { ... } );
exécuteur
resolve
et reject
. Cette fonction est exécutée immédiatement par l'implémentation de Promise
qui fournit les fonctions resolve
et reject
(elle est exécutée avant que le constructeur Promise
ait renvoyé l'objet créé). Les fonctions resolve
et reject
, 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 resolve
(si tout s'est bien passé) ou la fonction reject
(lorsqu'il y a eu un problème) pour définir l'état final de la promesse.L'interface Promise
représente un intermédiaire (proxy) 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).
Une Promise
est dans un de ces états :
Une promesse en attente peut être tenue avec une valeur ou rompue avec une raison (erreur). Quand on arrive à l'une des deux situations, les gestionnaires associés lors de l'appel de la méthode then
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).
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 composition.
Note: Une promesse est dans l'état settled (acquittée) qu'elle soit tenue ou rompue mais plus en attente. Le terme resolved (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, States and fates (en anglais), contient de plus amples détails sur la terminologie utilisée.
Attention : D'autres langages utilisent des mécanismes d'évaluation à la volée (lazy evaluation) et de déport des calculs (deferring computations). Ces mécanismes sont également intitulés promesses (promises). 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. f = () => expression
) afin de créer une expression à évaluer plus tard et utiliser f()
pour l'évaluer au moment voulu.
Promise.length
Promise
.Promise
qui est rompue avec la raison donnée.Promise
qui est tenue (résolue) avec la valeur donnée. Si la valeur possède une méthode then
, 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.Promise
{{page('fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise/prototype','Propriétés')}}
{{page('fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise/prototype','Méthodes')}}
Pour créer une promesse, on utilise l'opérateur new
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 :
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 });
On peut ainsi obtenir des fonctions asynchrones en renvoyant une promesse :
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(); }); }
Dans le court exemple qui suit, on illustre le mécanisme d'une Promise
. La méthode testPromise()
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 1s
à 3s
(aléatoire). Le constructeur Promise() est utilisé pour créer la promesse.
Le fait que la promesse soit tenue est simplement enregistré via un callback sur p1.then()
. Quelques indicateurs illustrent la manière dont la partie synchrone est découplée de la partie asynchrone.
'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/>'); }
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 Promise
. 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.
{{EmbedLiveSample('Exemple_interactif', '500', '200')}}
Un autre exemple simple utilisant Promise
et {{domxref("XMLHttpRequest")}} afin de charger une image est disponible sur le dépôt GitHub MDN js-examples. Vous pouvez également voir le résultat. Chaque étape est commentée afin de vous permettre de suivre l'état de la promesse et l'architecture utilisée avec XHR.
Spécification | État | Commentaires |
---|---|---|
{{SpecName('ES2015', '#sec-promise-objects', 'Promise')}} | {{Spec2('ES2015')}} | Définition initiale au sein d'un standard ECMA. |
{{SpecName('ESDraft', '#sec-promise-objects', 'Promise')}} | {{Spec2('ESDraft')}} |
{{Compat("javascript.builtins.Promise")}}