[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Promise [Back]  [Original]

Promise - JavaScript | MDN

Cette page a t traduite partir de l'anglais par la communaut. Vous pouvez contribuer en rejoignant la communaut francophone sur MDN Web Docs.

View in English Always switch to English

Promise

Baseline
Large disponibilit
*

Cette fonctionnalit est bien tablie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis juillet 2015.

* Certaines parties de cette fonctionnalit peuvent bnficier de prise en charge variables.

L'objet Promise reprsente un objet qui incarne la compltion ventuelle (ou l'chec) d'une opration asynchrone et sa valeur rsultante.

Pour comprendre le fonctionnement des promesses et comment les utiliser, nous vous conseillons de commencer par l'article du guide Utiliser les promesses JavaScript.

Dans cet article

Description

Une promesse (Promise) est un mandataire pour une valeur qui n'est pas ncessairement connue au moment de la cration de la promesse. Cela permet d'associer des gestionnaires au succs ventuel d'une action asynchrone et la raison d'une erreur. Ainsi, les mthodes asynchrones peuvent retourner des valeurs de manire similaire aux mthodes synchrones : au lieu de retourner immdiatement la valeur finale, la mthode asynchrone retourne une promesse pour fournir la valeur un moment donn dans le futur.

Une promesse (Promise) est dans l'un de ces tats :

  • pending (en attente) : tat initial, la promesse n'est ni complte, ni rompue.
  • fulfilled (complte) : signifiant que l'opration a t complte avec succs.
  • rejected (rompue) : signifiant que l'opration a chou.

L'tat ventuel d'une promesse en attente peut tre soit complte avec une valeur, soit rompue avec une raison (erreur). Lorsque l'une de ces options se produit, les gestionnaires associs mis en file d'attente par la mthode then d'une promesse sont appels. Si la promesse a dj t complte ou rompue lorsqu'un gestionnaire correspondant est attach, le gestionnaire est appel, de sorte qu'il n'y a pas de condition de concurrence entre l'achvement d'une opration asynchrone et l'attachement de ses gestionnaires.

Une promesse est dite acquitte (settled en anglais) si elle est soit complte, soit rompue, mais pas en attente.

Schma illustrant comment l'tat d'une promesse passe de en attente,  complte ou rompue par les gestionnaires then/catch. Une promesse en attente peut devenir soit complte, soit rompue. Si elle est complte, le gestionnaire  en compltion , ou premier paramtre de la mthode then(), est excut et effectue d'autres actions asynchrones. Si elle est rompue, le gestionnaire d'erreur, soit pass comme second paramtre de la mthode then(), soit comme seul paramtre de la mthode catch(), est excut. [Schma illustrant comment l'tat d'une promesse passe de en attente, complte ou rompue par les gestionnaires then/catch. Une promesse en attente peut devenir soit complte, soit rompue. Si elle est complte, le gestionnaire en compltion , ou premier paramtre de la mthode then(), est excut et effectue d'autres actions asynchrones. Si elle est rompue, le gestionnaire d'erreur, soit pass comme second paramtre de la mthode then(), soit comme seul paramtre de la mthode catch(), est excut.]

Vous entendez galement le terme rsolue utilis avec les promesses cela signifie que la promesse est acquitte ou  verrouille  pour correspondre l'tat ventuel d'une autre promesse, et que toute tentative de la rsoudre ou de la rompre ultrieurement n'a aucun effet. Le document tats et destins des promesses (angl.) de la proposition originale de Promise contient plus de dtails sur la terminologie des promesses. De manire informelle, les promesses  rsolues  sont souvent quivalentes aux promesses  compltes , mais comme illustr dans  tats et destins des promesses , les promesses rsolues peuvent galement tre en attente ou rompues. Par exemple :

js
new Promise((resolveOuter) => {
  resolveOuter(
    new Promise((resolveInner) => {
      setTimeout(resolveInner, 1000);
    }),
  );
});

Cette promesse est dj rsolue au moment o elle est cre (parce que le resolveOuter est appel de manire synchrone), mais elle est rsolue avec une autre promesse, et n'est donc pas complte avant 1 seconde plus tard, lorsque la promesse interne est complte. En pratique, la  rsolution  se fait souvent en coulisses et n'est pas observable, et seules sa compltion ou sa rupture le sont.

Note : D'autres langages ont des mcanismes pour l'valuation la vole (lazy evaluation en anglais) et le report d'un calcul (deferring computation en anglais), qu'ils appellent galement  promesses , par exemple Scheme. Les promesses en JavaScript reprsentent des processus qui sont dj en cours, et qui peuvent tre enchans avec des fonctions de rappel. Si vous souhaitez valuer la vole une expression, envisagez d'utiliser une fonction sans arguments, par exemple f = () => expression pour crer l'expression value la vole, et f() pour valuer l'expression immdiatement.

Une promesse (Promise) ne dispose pas en soi d'un protocole de premier niveau pour l'annulation, mais vous pouvez ventuellement annuler directement l'opration asynchrone sous-jacente, gnralement l'aide de AbortController.

Enchanement de promesses

Les mthodes de promesse then(), catch() et finally() sont utilises pour associer une action ultrieure une promesse lorsqu'elle devient acquitte. La mthode then() prend jusqu' deux arguments ; le premier argument est une fonction de rappel pour le cas de russite de la promesse, et le second argument est une fonction de rappel pour le cas de rejet. Les mthodes catch() et finally() appellent then() en interne et rendent la gestion des erreurs moins verbeuse. Par exemple, un catch() n'est en ralit qu'un then() sans passer le gestionnaire de russite. Comme ces mthodes retournent des promesses, elles peuvent tre chanes. Par exemple :

js
const maPromesse = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("toto");
  }, 300);
});

maPromesse
  .then(gestionnaireSuccesA, gestionnaireEchecA)
  .then(gestionnaireSuccesB, gestionnaireEchecB)
  .then(gestionnaireSuccesC, gestionnaireEchecC);

Nous utilisons la terminologie suivante : promesse initiale est la promesse sur laquelle then est appel ; nouvelle promesse est la promesse retourne par then. Les deux fonctions de rappel passes then sont appeles gestionnaire de russite et gestionnaire de rejet, respectivement.

L'tat d'acquittement de la promesse initiale dtermine quel gestionnaire excuter.

  • Si la promesse initiale est complte, le gestionnaire de russite est appel avec la valeur de russite.
  • Si la promesse initiale est rompue, le gestionnaire de rejet est appel avec la raison de l'chec.

La terminaison du gestionnaire dtermine l'tat d'acquittement de la nouvelle promesse.

  • Si le gestionnaire retourne une valeur de semi-promesse, la nouvelle promesse s'acquitte dans le mme tat que la valeur retourne.
  • Si le gestionnaire retourne une valeur qui n'est pas une semi-promesse, la nouvelle promesse est complte avec la valeur retourne.
  • Si le gestionnaire lve une erreur, la nouvelle promesse est rompue avec l'erreur leve.
  • Si la promesse initiale n'a pas de gestionnaire correspondant attach, la nouvelle promesse s'acquitte dans le mme tat que la promesse initiale c'est--dire que, sans gestionnaire de rejet, une promesse rompue reste rompue avec la mme raison.

Par exemple, dans le code ci-dessus, si maPromesse est rompue, gestionnaireEchecA est appele, et si gestionnaireEchecA s'excute normalement (sans lever d'exception ni retourner une promesse rompue), la promesse retourne par le premier then est complte au lieu de rester rompue. Par consquent, si une erreur doit tre gre immdiatement, mais que l'on souhaite conserver l'tat d'erreur tout au long de la chane, il faut lever une erreur d'un certain type dans le gestionnaire de rejet. En revanche, en l'absence de ncessit immdiate, on peut omettre la gestion des erreurs jusqu'au gestionnaire catch() final.

js
maPromesse
  .then(gestionnaireSuccesA)
  .then(gestionnaireSuccesB)
  .then(gestionnaireSuccesC)
  .catch(gestionnaireToutEchec);

Utilisez les fonctions flches pour les fonctions de rappel, l'implmentation de la chane de promesses peut ressembler ceci :

js
maPromesse
  .then((valeur) => `${valeur} et truc`)
  .then((valeur) => `${valeur} et truc blabla`)
  .then((valeur) => `${valeur} et blabla`)
  .then((valeur) => `${valeur} et blabla`)
  .then((valeur) => {
    console.log(valeur);
  })
  .catch((err) => {
    console.error(err);
  });

Note : Pour une excution plus rapide, toutes les actions synchrones doivent de prfrence tre effectues dans un seul gestionnaire, sinon il faut plusieurs battements d'horloge (ticks en anglais) pour excuter tous les gestionnaires en squence.

JavaScript maintient une file de tches. chaque fois, JavaScript choisit une tche dans la file et l'excute jusqu' son terme. Les tches sont dfinies par l'excuteur du constructeur Promise(), les gestionnaires passs then, ou toute API de la plateforme qui retourne une promesse. Les promesses dans une chane reprsentent la relation de dpendance entre ces tches. Lorsqu'une promesse est acquitte, les gestionnaires respectifs qui y sont associs sont ajouts l'arrire de la file de tches.

Une promesse peut participer plus d'une chane. Pour le code suivant, l'acquittement de promesseA entrane l'ajout de gestionSucces1 et gestionSucces2 la file de tches. Comme gestionSucces1 est enregistr en premier, il est invoqu en premier.

js
const promesseA = new Promise(uneFonction);
const promesseB = promesseA.then(gestionSucces1, gestionEchec1);
const promesseC = promesseA.then(gestionSucces2, gestionEchec2);

Une action peut tre affecte une promesse dj acquitte. Dans ce cas, l'action est ajoute immdiatement l'arrire de la file de tches et est excute lorsque toutes les tches existantes sont termines. Par consquent, une action pour une promesse dj  acquitte  ne se produit qu'aprs l'excution du code synchrone actuel et aprs qu'au moins un battement d'horloge se soit coul. Cela garantit que les actions des promesses sont asynchrones.

js
const promesseA = new Promise((resolutionFunc, rejectionFunc) => {
  resolutionFunc(777);
});
// Ici,  promesseA  est dj acquitte.
promesseA.then((val) =>
  console.log("journalisation asynchrone / val vaut :", val),
);
console.log("journalisation immdiate");

// produit les rsultats dans cet ordre :
// journalisation immdiate
// journalisation asynchrone / val vaut : 777

Semi-promesse

L'cosystme JavaScript a cr plusieurs implmentations de promesse bien avant qu'elles ne fassent partie du langage. Bien qu'elles soient reprsentes diffremment en interne, au minimum, tous les objets de type promesse implmentent l'interface Thenable. Une semi-promesse implmente la mthode .then(), qui est appele avec deux fonctions de rappel : un pour lorsque la promesse est complte, un pour lorsqu'elle est rompue. Les promesses sont galement des semi-promesses.

Pour interagir avec les implmentations existantes, le langage permet d'utiliser des semi-promesses la place des promesses. Par exemple, Promise.resolve ne rsout pas seulement les promesses, mais suit galement les semi-promesses.

js
// Cet objet n'est pas un semi-promesse conforme  Promises/A+ ! Il appelle
// enCompletion de manire synchrone.  des fins de dmonstration uniquement.
const semiPromesse = {
  then(enCompletion, auRejet) {
    enCompletion({
      // La semi-promesse est complte avec un autre semi-promesse
      then(enCompletion, auRejet) {
        enCompletion(42);
      },
    });
  },
};

Promise.resolve(semiPromesse); // Une promesse complte avec 42

La mthode then() est responsable de la planification de l'excution des fonctions de rappel enCompletion et auRejet fournies. Sa smantique, y compris la gestion des erreurs et l'asynchronicit, est dfinie avec prcision dans la spcification Promises/A+ (angl.), et nous ne la rptons pas ici. Il est trs rare que vous ayez besoin d'implmenter vous-mme une semi-promesse ; mme si vous n'utilisez pas les promesses natives, vous utilisez probablement une bibliothque de promesses telle que Bluebird (angl.).

Concurrence des promesses

La classe Promise offre quatre principales mthodes statiques pour faciliter la concurrence (angl.) des tches asynchrones :

Promise.all()

Se complte lorsque toutes les promesses sont compltes ; se rompt lorsque l'une des promesses se rompt.

Promise.allSettled()

Se complte lorsque toutes les promesses sont acquittes.

Promise.any()

Se complte lorsque l'une des promesses est complte ; se rompt lorsque toutes les promesses se rompent.

Promise.race()

S'acquitte lorsque l'une des promesses est acquitte. En d'autres termes, se complte lorsque l'une des promesses est complte ; se rompt lorsque l'une des promesses se rompt.

Toutes ces mthodes prennent un itrable de promesses (semi-promesses, pour tre exact) et retournent une nouvelle promesse. Elles prennent toutes en charge la sous-classification, ce qui signifie qu'elles peuvent tre appeles sur des sous-classes de Promise, et le rsultat est une promesse du type de la sous-classe. Pour ce faire, le constructeur de la sous-classe doit implmenter la mme signature que le constructeur Promise() acceptant une seule fonction executor qui peut tre appele avec les rappels resolve et reject comme paramtres. La sous-classe doit galement avoir une mthode statique resolve qui peut tre appele comme Promise.resolve() pour rsoudre des valeurs en promesses.

Il existe deux autres mthodes statiques pratiques : Promise.allKeyed() et Promise.allSettledKeyed(), qui se comportent comme Promise.all() et Promise.allSettled(), mais prennent des objets de promesses et retournent des promesses qui se compltent avec des objets de la mme forme. En travaillant avec des objets au lieu de tableaux, vous pouvez associer les rsultats des cls smantiquement significatives, au lieu d'un ordre de tableau arbitraire qui peut tre difficile maintenir.

Ces mthodes attachent des gestionnaires chaque promesse d'entre en utilisant then(). Mme lorsque la promesse rsultante est acquitte tt (par exemple lorsqu'une entre dans Promise.race() est acquitte), les autres gestionnaires ne sont pas supprims. Passer de manire rpte la mme promesse en attente aux mthodes de concurrence peut accumuler des gestionnaires mme lorsque ces gestionnaires ne sont jamais utiliss :

js
const promesseEnAttente = new Promise(() => {});

for (let i = 0; i < 1000; i++) {
  await Promise.race([Promise.resolve(0), promesseEnAttente]);
}
// Toutes les tches sont termines, mais promesseEnAttente conserve les
// gestionnaires attachs par les 1000 courses.

Les promesses ne fournissent aucun moyen de se dsabonner de ces gestionnaires ; ils restent attachs tant que la promesse d'entre est en attente et accessible. Dans la mesure du possible, annulez l'opration sous-jacente en utilisant un AbortSignal lorsque la promesse en attente n'est plus utile.

Notez que JavaScript fonctionne sur un processus unique par nature ; un instant donn, une seule tche est en cours d'excution, bien que le contrle puisse passer d'une promesse l'autre, donnant l'impression que l'excution des promesses est concurrente. L'excution parallle (angl.) en JavaScript ne peut tre ralise que par le biais de processus de travail.

Constructeur

Promise()

Cre un nouvel objet Promise. Le constructeur est principalement utilis pour envelopper des fonctions qui ne prennent pas en charge les promesses.

Proprits statiques

Promise[Symbol.species]

Retourne le constructeur utilis pour construire les valeurs de retour des mthodes de promesse.

Mthodes statiques

Promise.all()

Prend un itrable de promesses en entre et retourne une seule Promise. Cette promesse retourne est acquitte lorsque toutes les promesses de l'entre sont acquittes (y compris lorsqu'un itrable vide est pass), avec un tableau des valeurs d'acquittement. Elle est rompue lorsque l'une des promesses de l'entre est rompue, avec cette premire raison de rejet.

Promise.allKeyed()

Comme Promise.all(), sauf qu'elle prend un objet de promesses et retourne une promesse qui se complte avec un objet de la mme forme, vous permettant d'associer les rsultats des cls smantiquement significatives.

Promise.allSettled()

Prend un itrable de promesses en entre et retourne une seule promesse (Promise). Cette promesse retourne est acquitte lorsque toutes les promesses de l'entre sont acquittes (y compris lorsqu'un itrable vide est pass), avec un tableau d'objets qui dcrivent le rsultat de chaque promesse.

Promise.allSettledKeyed()

Comme Promise.allSettled(), sauf qu'elle prend un objet de promesses et retourne une promesse qui se complte avec un objet de la mme forme, vous permettant d'associer les rsultats des cls smantiquement significatives.

Promise.any()

Prend un itrable de promesses en entre et retourne une seule Promise. Cette promesse retourne est acquitte lorsque l'une des promesses de l'entre est acquitte, avec cette premire valeur d'acquittement. Elle est rompue lorsque toutes les promesses de l'entre sont rompues (y compris lorsqu'un itrable vide est pass), avec un AggregateError contenant un tableau de raisons de rejet.

Promise.race()

Prend un itrable de promesses en entre et retourne une seule Promise. Cette promesse retourne est acquitte avec l'tat final de la premire promesse qui s'acquitte.

Promise.reject()

Retourne un nouvel objet Promise qui est rompu avec la raison donne.

Promise.resolve()

Retourne un objet Promise qui est rsolu avec la valeur donne. Si la valeur est une semi-promesse (c'est--dire qu'elle possde une mthode then), la promesse retourne  suit  cette semi-promesse, adoptant son tat final ; sinon, la promesse retourne est acquitte avec la valeur.

Promise.try()

Prend une fonction de rappel de n'importe quel type (qui retourne ou lve une exception, de manire synchrone ou asynchrone) et encapsule son rsultat dans une promesse (Promise).

Promise.withResolvers()

Retourne un objet contenant un nouvel objet Promise et deux fonctions permettant de le rsoudre ou de le rompre, correspondant aux deux paramtres transmis l'excuteur du constructeur Promise().

Proprits d'instance

Ces proprits sont dfinies sur Promise.prototype et partages par toutes les instances de Promise.

Promise.prototype.constructor

La fonction constructeur qui a cr l'objet instance. Pour les instances de Promise, la valeur initiale est le constructeur Promise.

Promise.prototype[Symbol.toStringTag]

La valeur initiale de la proprit [Symbol.toStringTag] est la chane de caractres "Promise". Cette proprit est utilise dans Object.prototype.toString().

Mthodes d'instance

Promise.prototype.catch()

Ajoute une fonction de rappel comme gestionnaire d'chec la promesse et retourne une nouvelle promesse dont la valeur de rsolution est la valeur de retour de la fonction de rappel si cette dernire est appele ou sinon la valeur de rsolution originale de la promesse si celle-ci a russi.

Promise.prototype.finally()

Ajoute un gestionnaire la promesse et retourne une nouvelle promesse qui est rsolue lorsque la promesse originale est rsolue. Le gestionnaire est appel lorsque la promesse est rgle, qu'elle soit complte ou rompue.

Promise.prototype.then()

Ajoute des gestionnaires de succs et d'chec la promesse, et retourne une nouvelle promesse qui se rsout avec la valeur de retour du gestionnaire appel, ou avec sa valeur initiale si la promesse n'a pas t traite (c'est--dire si le gestionnaire pertinent onFulfilled ou onRejected n'est pas une fonction).

Exemples

Exemple simple

Dans cet exemple, nous utilisons setTimeout(...) pour simuler du code asynchrone. En ralit, vous allez utiliser probablement quelque chose comme XHR ou une API HTML.

js
const maPremierePromesse = new Promise((resolve, reject) => {
  // Nous appelons resolve(...) lorsque ce que nous faisions de manire
  // asynchrone a russi, et reject(...) lorsqu'il a chou.
  setTimeout(() => {
    resolve("Succs !"); // Super ! Tout s'est bien pass !
  }, 250);
});

maPremierePromesse.then((messageReussite) => {
  // messageReussite correspond  ce qui a t pass  la fonction resolve(...) ci-dessus.
  // Cela n'a pas besoin d'tre une chane de caractres, mais si c'est uniquement un message de succs, c'est probablement le cas.
  console.log(`Youpi ! ${messageReussite}`);
});

Exemple avec plusieurs situations

Cet exemple illustre diffrentes techniques d'utilisation des promesses et diffrentes situations qui peuvent se produire. Pour comprendre cela, commencez par faire dfiler jusqu'en bas du bloc de code et examinez la chane de promesses. Lorsqu'une promesse initiale est fournie, une chane de promesses peut suivre. La chane est compose d'appels .then(), et comporte gnralement (mais pas ncessairement) un seul .catch() la fin, ventuellement suivi d'un .finally(). Dans cet exemple, la chane de promesses est initie par une construction new Promise() crite sur mesure ; mais en pratique, les chanes de promesses commencent plus typiquement par une fonction d'API (crite par quelqu'un d'autre) qui retourne une promesse.

L'exemple de fonction tetheredGetNumber() montre qu'un gnrateur de promesses utilise reject() lors de la configuration d'un appel asynchrone, ou dans le rappel, ou les deux. La fonction promiseGetWord() illustre comment une fonction d'API peut gnrer et retourner une promesse de manire autonome.

Notez que la fonction problemePourObtenirNombre() se termine par un throw. Cela est ncessaire, car une chane de promesses passe par toutes les promesses .then(), mme aprs une erreur, et sans le throw, l'erreur semble  corrige . C'est gnant, et pour cette raison, il est courant d'omettre onRejected tout au long de la chane de promesses .then(), et d'avoir simplement un seul onRejected dans le catch() final.

Ce code peut tre excut sous Node.js. La comprhension est amliore en voyant les erreurs se produire rellement. Pour forcer davantage d'erreurs, modifiez les valeurs de SEUIL_A.

js
// Pour exprimenter la gestion des erreurs, les valeurs de  seuil  provoquent des erreurs de manire alatoire
const SEUIL_A = 8; // Abaissez ce seuil  0 pour forcer les erreurs

function tetheredGetNumber(resolve, reject) {
  setTimeout(() => {
    const entierAleatoire = Date.now();
    const valeur = entierAleatoire % 10;
    if (valeur < SEUIL_A) {
      resolve(valeur);
    } else {
      reject(new RangeError(`Trop grand : ${valeur}`));
    }
  }, 500);
}

function determinerParite(valeur) {
  const estImpair = valeur % 2 === 1;
  return { valeur, estImpair };
}

function problemePourObtenirNombre(raison) {
  const err = new Error("Problme pour obtenir le nombre", { cause: raison });
  console.error(err);
  throw err;
}

function promesseObtenirMot(infoParite) {
  return new Promise((resolve, reject) => {
    const { valeur, estImpair } = infoParite;
    if (valeur >= SEUIL_A - 1) {
      reject(new RangeError(`Toujours trop grand : ${valeur}`));
    } else {
      infoParite.motPairImpair = estImpair ? "impair" : "pair";
      resolve(infoParite);
    }
  });
}

new Promise(tetheredGetNumber)
  .then(determinerParite, problemePourObtenirNombre)
  .then(promesseObtenirMot)
  .then((info) => {
    console.log(`A obtenu : ${info.valeur}, ${info.motPairImpair}`);
    return info;
  })
  .catch((raison) => {
    if (raison.cause) {
      console.error("Erreur prcdemment gre");
    } else {
      console.error(`Problme avec promiseGetWord(): ${raison}`);
    }
  })
  .finally((info) => console.log("Tout est fini"));

Exemple avanc

Ce court exemple illustre le mcanisme d'une promesse (Promise). La mthode testPromesse() est appele chaque fois qu'on clique sur l'lment <button>. Cette mthode cre une promesse qui est complte grce la fonction setTimeout(), et avec la valeur comptePromesse (nombre commenant 1) aprs 1s 3s (alatoire). Le constructeur Promise() est utilis pour crer la promesse.

La compltion de la promesse est enregistre, par une fonction de rappel de russite dfinie avec p1.then(). Quelques indicateurs montrent comment la partie synchrone de la mthode est dcouple de l'achvement asynchrone de la promesse.

En cliquant sur le bouton plusieurs fois en peu de temps, vous voyez mme les diffrentes promesses tre compltes les unes aprs les autres.

HTML

html
<button id="faire-promesse">Crer un objet Promise !</button>
<div id="journal"></div>

JavaScript

js
"use strict";

let comptePromesse = 0;

function testPromesse() {
  const ceComptePromesse = ++comptePromesse;
  const journal = document.getElementById("journal");
  // dbut
  journal.insertAdjacentHTML("beforeend", `${ceComptePromesse}) Dmarrage<br>`);
  // Nous crons une nouvelle promesse : nous promettons un compte numrique de cette promesse,
  // en commenant  1 (aprs avoir attendu 3s)
  const p1 = new Promise((resolve, reject) => {
    // La fonction de rsolution est appele avec la capacit de
    // tenir ou de rompre la promesse
    journal.insertAdjacentHTML(
      "beforeend",
      `${ceComptePromesse}) Construction de la promesse<br>`,
    );
    // Ceci n'est qu'un exemple pour crer de l'asynchronisme
    setTimeout(
      () => {
        // Nous tenons la promesse
        resolve(ceComptePromesse);
      },
      Math.random() * 2000 + 1000,
    );
  });

  // Nous dfinissons ce qu'il faut faire lorsque la promesse est complte avec l'appel then(),
  // et ce qu'il faut faire lorsque la promesse est rompue avec l'appel catch()
  p1.then((val) => {
    // Nous affichons la valeur de la promesse complte
    journal.insertAdjacentHTML("beforeend", `${val}) Promesse complte<br>`);
  }).catch((reason) => {
    // Journalisation de la raison du rejet
    console.log(`Grer la promesse rompue (${reason}) ici.`);
  });
  // fin
  journal.insertAdjacentHTML(
    "beforeend",
    `${ceComptePromesse}) Promesse cre<br>`,
  );
}

const btn = document.getElementById("faire-promesse");
btn.addEventListener("click", testPromesse);

Rsultat

Charger une image en XHR

Un autre exemple utilisant Promise et XMLHttpRequest pour charger une image est prsent ci-dessous. Chaque tape est commente afin de vous permettre de suivre l'tat de la promesse et l'architecture utilise avec XHR.

js
function chargerImage(url) {
  // Cre une nouvelle promesse avec le constructeur Promise();
  // Cela a pour argument une fonction avec deux paramtres, resolve et reject
  return new Promise((resolve, reject) => {
    // XHR pour charger une image
    const requete = new XMLHttpRequest();
    requete.open("GET", url);
    requete.responseType = "blob";
    // Lorsque la requte se charge, vrifiez si elle a russi
    requete.onload = () => {
      if (requete.status === 200) {
        // Si elle russit, rsolvez la promesse en renvoyant la rponse de la requte
        resolve(requete.response);
      } else {
        // Si elle choue, rompez la promesse avec un message d'erreur
        reject(
          Error(
            `L'image n'a pas t charge avec succs ; code d'erreur : + ${requete.statusText}`,
          ),
        );
      }
    };
    // Gre les erreurs rseau
    requete.onerror = () => reject(new Error("Il y a eu une erreur rseau."));
    // Envoie la requte
    requete.send();
  });
}

// Obtient une rfrence  l'lment body et cre un nouvel objet image
const body = document.querySelector("body");
const monImage = new Image();
const imgUrl =
  "https://mdn.github.io/shared-assets/images/examples/round-balloon.png";

// Appelle la fonction avec l'URL que nous voulons charger, puis enchane
// la mthode then() de la promesse avec deux fonctions de rappel
chargerImage(imgUrl).then(
  (reponse) => {
    // La premire s'excute lorsque la promesse est rsolue, avec la
    // response de la requte dfinie dans la mthode resolve().
    const imageURL = URL.createObjectURL(reponse);
    monImage.src = imageURL;
    body.appendChild(monImage);
  },
  (erreur) => {
    // La seconde s'excute lorsque la promesse est rompue,
    // et affiche l'erreur dfinie avec la mthode reject().
    console.log(erreur);
  },
);

Suivre l'objet de paramtres actuel

Un objet de paramtres est un environnement (angl.) qui fournit des informations supplmentaires lors de l'excution du code JavaScript. Cela inclut la carte des domaines et des modules, ainsi que des informations spcifiques au HTML telles que l'origine. L'objet de paramtres actuel est suivi afin de garantir que le navigateur sache lequel utiliser pour un morceau de code utilisateurice donn.

Pour mieux comprendre cela, nous pouvons examiner de plus prs comment le domaine peut poser problme. Un domaine peut tre grossirement considr comme l'objet global. Ce qui est unique avec les domaines, c'est qu'ils contiennent toutes les informations ncessaires pour excuter du code JavaScript. Cela inclut des objets comme Array et Error. Chaque objet de paramtres a sa propre  copie  de ces objets et ils ne sont pas partags. Cela peut provoquer un comportement inattendu en relation avec les promesses. Pour contourner ce problme, nous suivons quelque chose appel objet de paramtres actuel. Cela reprsente des informations spcifiques au contexte du code utilisateurice responsable d'un certain appel de fonction.

Pour illustrer cela un peu plus en dtail, nous pouvons examiner comment un <iframe> intgr dans un document communique avec son hte. Comme toutes les API web sont conscientes de l'objet de paramtres actuel, ce qui suit fonctionne dans tous les navigateurs :

html
<!doctype html>
<iframe></iframe>
<!-- nous avons un domaine ici -->
<script>
  // nous avons un domaine ici aussi
  const liaison = frames[0].postMessage.bind(frames[0], "des donnes", "*");
  // liaison est une fonction native  il n'y a pas de code
  // utilisateurice sur la pile, alors quel domaine utilisons-nous ?
  setTimeout(liaison);
  // cela fonctionne toujours, car nous utilisons le plus jeune
  // domaine (l'objet de paramtres actuel) sur la pile
</script>

Le mme concept s'applique aux promesses. Si nous modifions un peu l'exemple ci-dessus, nous obtenons ceci :

html
<!doctype html>
<iframe></iframe>
<!-- nous avons un domaine ici -->
<script>
  // nous avons un domaine ici aussi
  const liaison = frames[0].postMessage.bind(frames[0], "des donnes", "*");
  // liaison est une fonction native  il n'y a pas de code
  // utilisateurice sur la pile  alors quel domaine utilisons-nous ?
  Promise.resolve(undefined).then(liaison);
  // cela fonctionne toujours, car nous utilisons le plus jeune
  // domaine (l'objet de paramtres actuel) sur la pile
</script>

Si nous modifions cela de sorte qu'un <iframe> dans le document coute les messages posts, nous pouvons observer l'effet de l'objet de paramtres actuel :

html
<!-- y.html -->
<!doctype html>
<iframe src="x.html"></iframe>
<script>
  const liaison = frames[0].postMessage.bind(frames[0], "des donnes", "*");
  Promise.resolve(undefined).then(liaison);
</script>
html
<!-- x.html -->
<!doctype html>
<script>
  window.addEventListener("message", (event) => {
    document.querySelector("#text").textContent = "hello";
    // ce code ne s'excute que dans les navigateurs qui suivent l'objet de paramtres actuel
    console.log(event);
  });
</script>

Dans l'exemple ci-dessus, le texte interne d'un <iframe> n'est mis jour que si l'objet de paramtres actuel est suivi. En effet, sans suivi de l'objet de paramtres actuel, nous pourrions finir par utiliser le mauvais environnement pour envoyer le message.

Note : Actuellement, le suivi de l'objet de paramtres actuel est entirement implment dans Firefox, et partiellement dans Chrome et Safari.

Spcifications

Spcification
ECMAScript 2027 LanguageSpecification
# sec-promise-objects

Compatibilit des navigateurs

Voir aussi


Web Proxy Viewer  |  New URL  |  Original Page