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.
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 :
Créer une promesse personnalisée, comme XPromise, permet une compréhension plus approfondie de son fonctionnement interne :
Passons en revue le code de XPromise, en explorant chaque composant qui le fait fonctionner exactement comme les promesses natives de JavaScript.
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); } // ... }
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); } // ... }
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); }
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); } }
Satisfaire et rejeter :
Finalisation des gestionnaires en file d'attente :
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); }
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); } }
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 :
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!