ホームページ  >  記事  >  ウェブフロントエンド  >  XPromise の構築: カスタム JavaScript Promise の詳細

XPromise の構築: カスタム JavaScript Promise の詳細

Linda Hamilton
Linda Hamiltonオリジナル
2024-10-26 13:40:03725ブラウズ

JavaScript は非同期の性質があることで知られており、他のプロセスをブロックすることなく、データのフェッチ、アニメーション、ファイル処理などの操作を可能にします。 Promise は非同期操作を適切に処理するための中心であり、コードをよりクリーンで管理しやすくします。このプロジェクト XPromise は JavaScript Promise のカスタム実装であり、Promise メカニズムが内部でどのように動作するかを調査するのに役立ちます。

完全な実装は GitHub で確認できます。

約束とは何ですか?

JavaScript の Promise は、非同期操作の最終的な完了または失敗を表す特別なオブジェクトです。 Promise を使用すると、いつ完了するかわからない場合でも、タスクの完了後に実行する操作をキューに入れることができます。 Promise のユニークな点は次のとおりです:

  1. 3 つの状態: 約束は、保留中履行、または 拒否のいずれかになります。
  2. 不変の状態変更: Promise が解決されると (履行または拒否され)、状態を変更することはできません。
  3. .then および .catch とのチェーン: Promise は、満たされた値を処理するための .then() とエラーを処理するための .catch() を提供し、それらを構成可能にします。

Building XPromise: A Deep Dive into Custom JavaScript Promises

カスタム Promise を作成する理由

XPromise などのカスタム Promise を作成すると、その内部の仕組みをより深く理解できます。

  • 状態管理: 最終状態が 1 つだけになるように状態を処理します。
  • コールバック キューイング: Promise は、解決後に実行されるコールバックをキューに入れる必要があります。
  • エラー処理: ネイティブの 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);
  }
  // ...
}
  1. コンストラクターと初期セットアップ:
    • XPromise はすぐに実行されるエグゼキューター関数を受け入れます。
    • this.state は現在の状態を追跡し、this.queue は .then() 呼び出しによってキューに入れられたすべての関数を保持します。

then、catch、finally メソッドの追加

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);
  }
  // ...
}
  1. then: then メソッドは、新しい XPromise インスタンスを作成し、それを onFulfilled および onRejected コールバックとともに保存します。これにより、チェーン内の次の Promise が前の Promise の出力を確実に受け取るようになります。
  2. catch: エラー処理の省略表現。then(null, onRejected) を呼び出すのと同等です。
  3. finally: Promise の結果に関係なく実行されるクリーンアップ アクションを処理します。

ハンドルを使用した解決済み状態の管理

ハンドル関数は、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);
  }
}
  1. 履行および拒否:

    • 履行および拒否により Promise が完成し、その状態と値が更新されます。
    • 値が Promise または thenable の場合、正しく処理されることを確認するために doResolve を延期します。
  2. キューに登録されたハンドラーを終了中:

    • Promise が解決されると、finale はキューを反復処理して、すべてのハンドラーを順番に実行します。

エグゼキュータ関数 doResolve

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の使用例

動作する 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 で非同期プログラミングがどのように管理されるかについて実践的な洞察が得られます。

  • 状態管理 は、Promise が 1 回だけ解決され、履行または拒否されたままになることを保証します。
  • コールバック キューにより、複数のチェーンされた .then() 呼び出しを効果的に処理できます。
  • catch を使用した エラー処理 は、最終的に非同期エラーを適切に処理するのに役立ちます。

コードをさらに詳しく調べるには、GitHub の XPromise プロジェクトをチェックしてください。コードを試し、自由にカスタマイズして、Promise の競合状態、チェーン、ネストなどのより高度な機能を探索してください。

以上がXPromise の構築: カスタム JavaScript Promise の詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。