Maison > interface Web > js tutoriel > le corps du texte

Construire XPromise : une plongée approfondie dans les promesses JavaScript personnalisées

Linda Hamilton
Libérer: 2024-10-26 13:40:03
original
724 Les gens l'ont consulté

JavaScript est connu pour sa nature asynchrone, permettant des opérations telles que la récupération de données, les animations et la gestion de fichiers sans bloquer d'autres processus. Les promesses sont au cœur de la gestion gracieuse des opérations asynchrones, rendant notre code plus propre et plus gérable. Ce projet, XPromise, est une implémentation personnalisée de JavaScript Promises, nous aidant à explorer le fonctionnement interne du mécanisme Promise.

Vous pouvez consulter la mise en œuvre complète sur GitHub.

Qu'est-ce qu'une promesse ?

Une promesse en JavaScript est un objet spécial représentant l'achèvement ou l'échec éventuel d'une opération asynchrone. Avec Promises, nous pouvons mettre en file d’attente les opérations à exécuter après l’achèvement d’une tâche, même si nous ne savons pas quand elle sera terminée. Voici ce qui rend une promesse unique :

  1. Trois États : Une promesse peut être En attente, Réalisée ou Rejetée.
  2. Changement d'état immuable : Une fois qu'une promesse est résolue (réalisée ou rejetée), elle ne peut pas changer d'état.
  3. Chaînage avec .then et .catch : les promesses fournissent .then() pour gérer les valeurs remplies et .catch() pour les erreurs, les rendant composables.

Building XPromise: A Deep Dive into Custom JavaScript Promises

Pourquoi créer une promesse personnalisée ?

Créer une promesse personnalisée, comme XPromise, permet une compréhension plus approfondie de son fonctionnement interne :

  • Gestion des états : Nous traitons les états de manière à garantir un seul état final.
  • Mise en file d'attente des rappels : La promesse doit mettre en file d'attente les rappels à exécuter une fois résolue.
  • Gestion des erreurs : il inclut un moyen de gérer les erreurs asynchrones avec élégance, en émulant le comportement natif de Promise.

Présentation du projet

Passons en revue le code de XPromise, en explorant chaque composant qui le fait fonctionner exactement comme les promesses natives de JavaScript.

Configuration des états et de la structure de base

XPromise commence par définir trois états : EN ATTENTE, FULFILLED et REJECTED.

const PENDING = "PENDING";
const FULFILLED = "FULFILLED";
const REJECTED = "REJECTED";

class XPromise {
  constructor(executor) {
    this.state = PENDING;
    this.queue = [];
    doResolve(this, executor);
  }
  // ...
}
Copier après la connexion
Copier après la connexion
  1. Constructeur et configuration initiale :
    • XPromise accepte une fonction d'exécuteur, qui s'exécute immédiatement.
    • this.state garde une trace de l'état actuel, tandis que this.queue contient toutes les fonctions mises en file d'attente par les appels .then().

Ajout des méthodes then, catch et enfin

Avec ensuite, catch et enfin, nous traitons les scénarios remplis, rejetés et de nettoyage. Voici comment XPromise réalise le chaînage :

const PENDING = "PENDING";
const FULFILLED = "FULFILLED";
const REJECTED = "REJECTED";

class XPromise {
  constructor(executor) {
    this.state = PENDING;
    this.queue = [];
    doResolve(this, executor);
  }
  // ...
}
Copier après la connexion
Copier après la connexion
  1. then : la méthode then crée une nouvelle instance XPromise et la stocke avec les rappels onFulfilled et onRejected. Cela garantit que la prochaine promesse de la chaîne reçoit la sortie de la précédente.
  2. catch : Un raccourci pour gérer les erreurs, équivalent à appeler then(null, onRejected).
  3. finally : gère les actions de nettoyage qui s'exécutent quel que soit le résultat de la promesse.

Gestion des états résolus avec handle

La fonction handle décide si la promesse est toujours en attente ou résolue. S'il est en attente, le gestionnaire est ajouté à la file d'attente pour être exécuté ultérieurement. Si la promesse est résolue, elle traite immédiatement le gestionnaire.

then(onFulfilled, onRejected) {
  const promise = new XPromise(() => {});
  handle(this, { promise, onFulfilled, onRejected });
  return promise;
}

catch(onRejected) {
  return this.then(null, onRejected);
}

finally(onFinally) {
  return this.then(onFinally, onFinally);
}
Copier après la connexion

Résoudre et rejeter les promesses

Les promesses remplies et rejetées nécessitent des fonctions spéciales pour gérer leurs résultats. Voici comment XPromise y parvient :

function handle(promise, handler) {
  while (promise.state !== REJECTED && promise.value instanceof XPromise) {
    promise = promise.value;
  }

  if (promise.state === PENDING) {
    promise.queue.push(handler);
  } else {
    handleResolved(promise, handler);
  }
}
Copier après la connexion
  1. Satisfaire et rejeter :

    • remplir et rejeter finaliser la promesse, en mettant à jour son état et sa valeur.
    • Si la valeur est une promesse ou alors possible, nous reportons à doResolve pour nous assurer qu'elle est gérée correctement.
  2. Finalisation des gestionnaires en file d'attente :

    • Une fois la promesse résolue, final parcourt la file d'attente pour exécuter tous les gestionnaires dans l'ordre.

La fonction exécuteur doResolve

La fonction doResolve exécute l'exécuteur en toute sécurité en encapsulant les appels de résolution et de rejet, empêchant ainsi tout autre changement d'état s'ils sont appelés plusieurs fois.

function fulfill(promise, value) {
  if (value === promise) {
    return reject(promise, new TypeError());
  }

  if (value && (typeof value === "object" || typeof value === "function")) {
    let then;
    try {
      then = value.then;
    } catch (e) {
      return reject(promise, e);
    }

    if (typeof then === "function") {
      return doResolve(promise, then.bind(value));
    }
  }

  promise.state = FULFILLED;
  promise.value = value;
  finale(promise);
}

function reject(promise, reason) {
  promise.state = REJECTED;
  promise.value = reason;
  finale(promise);
}
Copier après la connexion

Exemple d'utilisation de XPromise

Maintenant que nous avons une XPromise fonctionnelle, essayons-la avec un exemple simple :

function doResolve(promise, executor) {
  let called = false;
  function wrapFulfill(value) {
    if (called) return;
    called = true;
    fulfill(promise, value);
  }

  function wrapReject(reason) {
    if (called) return;
    called = true;
    reject(promise, reason);
  }
  try {
    executor(wrapFulfill, wrapReject);
  } catch (e) {
    wrapReject(e);
  }
}
Copier après la connexion

Points clés à retenir

Réimplémenter Promises à partir de zéro fournit un aperçu pratique de la manière dont la programmation asynchrone est gérée en JavaScript :

  • Gestion de l'État garantit que la promesse n'est résolue qu'une seule fois, restant soit remplie, soit rejetée.
  • Callback Queueing permet de gérer efficacement plusieurs appels .then() enchaînés.
  • Gestion des erreurs avec catch et aide enfin à gérer les erreurs asynchrones avec élégance.

Pour approfondir le code, consultez le projet XPromise sur GitHub. Expérimentez avec le code et n'hésitez pas à le personnaliser pour explorer des fonctionnalités plus avancées, telles que les conditions de course Promise, le chaînage et l'imbrication !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!