JavaScript は非同期の性質があることで知られており、他のプロセスをブロックすることなく、データのフェッチ、アニメーション、ファイル処理などの操作を可能にします。 Promise は非同期操作を適切に処理するための中心であり、コードをよりクリーンで管理しやすくします。このプロジェクト XPromise は JavaScript Promise のカスタム実装であり、Promise メカニズムが内部でどのように動作するかを調査するのに役立ちます。
完全な実装は GitHub で確認できます。
JavaScript の Promise は、非同期操作の最終的な完了または失敗を表す特別なオブジェクトです。 Promise を使用すると、いつ完了するかわからない場合でも、タスクの完了後に実行する操作をキューに入れることができます。 Promise のユニークな点は次のとおりです:
XPromise などのカスタム Promise を作成すると、その内部の仕組みをより深く理解できます。
XPromise のコードを見て、JavaScript のネイティブ Promises と同じように動作させる各コンポーネントを調べてみましょう。
XPromise は、PENDING、FULFILLED、REJECTED の 3 つの状態を定義することから始まります。
const PENDING = "PENDING"; const FULFILLED = "FULFILLED"; const REJECTED = "REJECTED"; class XPromise { constructor(executor) { this.state = PENDING; this.queue = []; doResolve(this, executor); } // ... }
then、catch、finally を使用して、実行、拒否、およびクリーンアップのシナリオを処理します。 XPromise がチェーンを実現する方法は次のとおりです:
const PENDING = "PENDING"; const FULFILLED = "FULFILLED"; const REJECTED = "REJECTED"; class XPromise { constructor(executor) { this.state = PENDING; this.queue = []; doResolve(this, executor); } // ... }
ハンドル関数は、Promise がまだ保留中であるか解決済みであるかを判断します。保留中の場合、ハンドラーはキューに追加され、後で実行されます。 Promise が解決されると、すぐにハンドラーが処理されます。
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); }
履行された Promise と拒否された Promise には、その結果を処理するための特別な関数が必要です。 XPromise がそれを実現する方法は次のとおりです:
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); } }
履行および拒否:
キューに登録されたハンドラーを終了中:
doResolve 関数は、resolve 呼び出しと拒否呼び出しをラップすることでエグゼキューターを安全に実行し、複数回呼び出されてもそれ以上の状態変更を防ぎます。
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); }
動作する XPromise ができたので、簡単な例で試してみましょう:
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); } }
Promise を最初から再実装すると、JavaScript で非同期プログラミングがどのように管理されるかについて実践的な洞察が得られます。
コードをさらに詳しく調べるには、GitHub の XPromise プロジェクトをチェックしてください。コードを試し、自由にカスタマイズして、Promise の競合状態、チェーン、ネストなどのより高度な機能を探索してください。
以上がXPromise の構築: カスタム JavaScript Promise の詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。