国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

ホームページ ウェブフロントエンド jsチュートリアル JavaScript で獨(dú)自の Promise を作成する

JavaScript で獨(dú)自の Promise を作成する

Dec 28, 2024 pm 01:29 PM

Create your own Promise in JavaScript

なぜ?

JavaScript Promise が內(nèi)部でどのようにコールバックを非同期的に実行するかを理解するため。

JavaScript で獨(dú)自の Promise を作成しましょう! Promise/A 仕様に従います。これは、Promise が非同期操作を処理し、解決、拒否し、予測(cè)可能なチェーンとエラー処理を保証する方法を概説しています。

話を簡(jiǎn)単にするために、Promises/A 仕様の ? でマークされている主要なルールに焦點(diǎn)を當(dāng)てます。これは完全な実裝ではなく、簡(jiǎn)略化されたバージョンになります。構(gòu)築するものは次のとおりです:

1. 用語(yǔ)

1.1 'promise' は、動(dòng)作がこの仕様に準(zhǔn)拠する then メソッドを持つオブジェクトまたは関數(shù)です。

1.2 thenable' は、then メソッドを定義するオブジェクトまたは関數(shù)です。

1.3 「?jìng)帯工?、任意の有効?JavaScript 値 (未定義、thenable、または Promise を含む) です。

1.4 「例外」は、throw ステートメントを使用してスローされる値です。

1.5 'reason' は、Promise が拒否された理由を示す値です。

2. 要件

2.1 プロミスの狀態(tài)

Promise は、保留中、履行済み、拒否の 3 つの狀態(tài)のいずれかである必要があります。

2.1.1.保留中の場(chǎng)合、約束: ?

?は、満たされた狀態(tài)または拒否された狀態(tài)のいずれかに移行する可能性があります。

2.1.2.果たされたときの約束: ?

?は他の狀態(tài)に遷移してはなりません。

?には値が必要であり、変更することはできません。

2.1.3.拒否された場(chǎng)合の約束: ?

?は他の狀態(tài)に遷移してはなりません。

?には理由があり、それを変えてはなりません。

2.2 當(dāng)時(shí)の方法

Promise は、その現(xiàn)在または最終的な値または理由にアクセスするための then メソッドを提供する必要があります。

Promise の then メソッドは 2 つの引數(shù)を受け入れます:

promise.then(onFulfilled, onRejected);

2.2.1. onFulfilled と onRejected は両方ともオプションの引數(shù)です: ?

? onFulfilled が関數(shù)ではない場(chǎng)合、無(wú)視する必要があります。

? onRejected が関數(shù)ではない場(chǎng)合、無(wú)視する必要があります。

2.2.2. onFulfilled が関數(shù)の場(chǎng)合: ?

? 最初の引數(shù)として Promise の値を指定して、Promise が実行された後に呼び出さなければなりません。

? 約束が果たされる前に呼び出してはなりません。

? 複數(shù)回呼び出すことはできません。

2.2.3. onRejected が関數(shù)の場(chǎng)合、?

? Promise が拒否された後に、Promise の理由を最初の引數(shù)として呼び出す必要があります。

? Promise が拒否される前に呼び出してはなりません。

? 複數(shù)回呼び出すことはできません。

2.2.4. onFulfilled または onRejected は、実行コンテキスト スタックにプラットフォーム コードのみが含まれるまで呼び出さないでください。 ?

2.2.5. onFulfilled と onRejected は関數(shù)として呼び出す必要があります (つまり、this 値なし)。 ?

2.2.6. then は同じ Promise で複數(shù)回呼び出される可能性があります。 ?

? Promise が履行された場(chǎng)合、それぞれの onFulfilled コールバックはすべて、then への呼び出しの順序で実行する必要があります。

? Promise が拒否された場(chǎng)合、すべての onRejected コールバックは、最初の then 呼び出しの順序で実行する必要があります。

2.2.7.その後、Promise を返さなければなりません。 ?

promise.then(onFulfilled, onRejected);

? onFulfilled または onRejected のいずれかが値 x を返した場(chǎng)合、Promise 解決プロシージャ [[Resolve]](promise2, x) を?qū)g行します。 ?

? onFulfilled または onRejected のいずれかが例外 e をスローした場(chǎng)合、promise2 は e を理由として拒否されなければなりません。 ?

? onFulfilled が関數(shù)ではなく、promise1 が履行される場(chǎng)合、promise2 はpromise1 と同じ?jìng)帳锹男肖丹欷胜堡欷肖胜辘蓼护蟆??

? onRejected が関數(shù)ではなく、promise1 が拒否された場(chǎng)合、promise2 は、promise1 と同じ理由で拒否されなければなりません。 ?

実裝

JavaScript Promise は引數(shù)として実行関數(shù)を受け取り、Promise が作成されるとすぐに呼び出されます。

promise2 = promise1.then(onFulfilled, onRejected);
new Promise(excecutor);

コアとなる Promises/A 仕様では、Promise を作成、履行、または拒否する方法については扱っていません。それはあなた次第です。ただし、Promise の構(gòu)築のために提供する実裝は、JavaScript の非同期 API と互換性がある必要があります。これが Promise クラスの最初のドラフトです:

const promise = new Promise((resolve, reject) => {
    // Runs some async or sync tasks
});

ルール 2.1 (約束の狀態(tài)) では、約束は保留、履行、または拒否の 3 つの狀態(tài)のいずれかでなければならないと規(guī)定されています。また、これらの各狀態(tài)で何が起こるかについても説明します。

Promise は、履行または拒否された場(chǎng)合、他の狀態(tài)に移行してはなりません。したがって、移行を行う前に、Promise が保留狀態(tài)であることを確認(rèn)する必要があります。

class YourPromise {
    constructor(executor) {
        this.state = 'pending';
        this.value = undefined;
        this.reason = undefined;

        const resolve = value => {
            if (this.state === 'pending') {
                this.state = 'fulfilled';
                this.value = value;
            }
        };

        const reject = reason => {
            if (this.state === 'pending') {
                this.state = 'rejected';
                this.reason = reason;
            }
        };

        try {
            executor(resolve, reject);  // The executor function being called immediately
        } catch (error) {
            reject(error);
        }
    }
}

Promise の初期狀態(tài)が保留中であることはすでにわかっており、明示的に履行または拒否されるまで保留中のままであることを保証します。

const resolve = value => {
    if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
    }
};

const reject = reason => {
    if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
    }
};

Executor 関數(shù)は Promise のインスタンス化直後に呼び出されるため、コンストラクター メソッド內(nèi)で呼び出します。

this.state = 'pending';

YourPromise クラスの最初のドラフトはここで完了します。

Promise/A 仕様は主に、相互運(yùn)用可能な then() メソッドの定義に焦點(diǎn)を當(dāng)てています。このメソッドを使用すると、Promise の現(xiàn)在または最終的な値または理由にアクセスできます。それでは、詳しく見(jiàn)ていきましょう。

ルール 2.2 (then メソッド) では、Promise には 2 つの引數(shù)を受け入れる then() メソッドが必要であると規(guī)定されています。

try {
    executor(resolve, reject);
} catch (error) {
    reject(error);
}

onFulfilled と onRejected は両方とも、promise が履行されるか拒否された後に呼び出す必要があります。関數(shù)の場(chǎng)合は、promise の値または理由を最初の引數(shù)として渡します。

class YourPromise {
    constructor(executor) {
        // Implementation
    }

    then(onFulfilled, onRejected) {
        // Implementation
    }
}

さらに、Promise が履行または拒否される前に呼び出してはならず、複數(shù)回呼び出してはなりません。 onFulfilled と onRejected は両方ともオプションであり、関數(shù)でない場(chǎng)合は無(wú)視する必要があります。

ルール 2.2、2.2.6、および 2.2.7 を見(jiàn)ると、Promise には then() メソッドが必要であり、then() メソッドは複數(shù)回呼び出すことができ、メソッドは約束:

promise.then(onFulfilled, onRejected);

物事を簡(jiǎn)単にするために、個(gè)別のクラスや関數(shù)は扱いません。 executor 関數(shù)を渡して、Promise オブジェクトを返します:

promise2 = promise1.then(onFulfilled, onRejected);

executor 関數(shù)內(nèi)で、Promise が履行された場(chǎng)合、onFulfilled コールバックを呼び出し、Promise の値で解決します。同様に、Promise が拒否された場(chǎng)合は、onRejected コールバックを呼び出し、Promise の理由を指定して拒否します。

次の質(zhì)問(wèn)は、Promise がまだ保留狀態(tài)にある場(chǎng)合に、onFulfilled コールバックと onRejected コールバックをどうするかということです。次のように、後で呼び出されるようにそれらをキューに入れます。

new Promise(excecutor);

これで完了です。これは、then() メソッドを含む Promise クラスの 2 番目のドラフトです:

const promise = new Promise((resolve, reject) => {
    // Runs some async or sync tasks
});

ここでは、コールバックを保持するキューとして、onFulfilledCallbacks と onRejectedCallbacks という 2 つのフィールドを?qū)毪筏蓼?。これらのキューには、Promise の保留中に then() 呼び出しを介してコールバックが設(shè)定され、Promise が履行または拒否されたときに呼び出されます。

Promise クラスをテストしてみましょう:

class YourPromise {
    constructor(executor) {
        this.state = 'pending';
        this.value = undefined;
        this.reason = undefined;

        const resolve = value => {
            if (this.state === 'pending') {
                this.state = 'fulfilled';
                this.value = value;
            }
        };

        const reject = reason => {
            if (this.state === 'pending') {
                this.state = 'rejected';
                this.reason = reason;
            }
        };

        try {
            executor(resolve, reject);  // The executor function being called immediately
        } catch (error) {
            reject(error);
        }
    }
}

次のように出力されるはずです:

const resolve = value => {
    if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
    }
};

const reject = reason => {
    if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
    }
};

一方、次のテストを?qū)g行すると:

this.state = 'pending';

次の結(jié)果が得られます:

try {
    executor(resolve, reject);
} catch (error) {
    reject(error);
}

代わりに:

class YourPromise {
    constructor(executor) {
        // Implementation
    }

    then(onFulfilled, onRejected) {
        // Implementation
    }
}

なぜですか?問(wèn)題は、then() が呼び出された時(shí)點(diǎn)で YourPromise インスタンスがすでに解決または拒否されている場(chǎng)合に、then() メソッドがコールバックを処理する方法にあります。具體的には、Promise 狀態(tài)が保留中でない場(chǎng)合、then() メソッドはコールバックの実行を次のマイクロタスク キューに適切に延期しません。そしてそれが同期実行を引き起こします。テスト例では:

? Promise は、「即時(shí)解決」という値で即時(shí)に解決されます。

? Promise.then() が呼び出されたとき、狀態(tài)はすでに満たされているため、onFulfilled コールバックは次のマイクロタスク キューに延期されることなく直接実行されます。

ここで、ルール 2.2.4 が適用されます。このルールにより、Promise がすでに解決または拒否されている場(chǎng)合でも、then() コールバック (onFulfilled または onRejected) が非同期で実行されることが保証されます。これは、現(xiàn)在の実行スタックが完全にクリアされ、プラットフォーム コード (イベント ループやマイクロタスク キューなど) のみが実行されるまで、コールバックを?qū)g行してはいけないことを意味します。

このルールがなぜ重要なのでしょうか?

このルールは、Promise/A 仕様の中で最も重要なルールの 1 つです。それは次のことを保証するためです:

? Promise がすぐに解決されたとしても、その then() コールバックはイベント ループの次のティックまで実行されません。

? この動(dòng)作は、setTimeout や process.nextTick などの JavaScript の他の非同期 API の動(dòng)作と一致しています。

どうすればこれを達(dá)成できるでしょうか?

これは、setTimeout や setImmediate などのマクロタスク メカニズム、または queueMicrotask や process.nextTick などのマイクロタスク メカニズムを使用して実現(xiàn)できます。マイクロタスク、マクロタスク、または同様のメカニズムのコールバックは、現(xiàn)在の JavaScript 実行コンテキストが終了した後に実行されるためです。

上記の問(wèn)題を解決するには、狀態(tài)がすでに満たされているか拒否されている場(chǎng)合でも、対応するコールバック (onFulfilled または onRejected) が queueMicrotask を使用して非同期に実行されるようにする必要があります。修正された実裝は次のとおりです:

promise.then(onFulfilled, onRejected);

前のサンプル テスト コードを再度実行します。次の出力が得られるはずです:

promise2 = promise1.then(onFulfilled, onRejected);

以上です。

ここまでで、then() からのコールバックがどのように延期され、次のマイクロタスク キューで実行され、非同期動(dòng)作が可能になるかについて明確に理解できたはずです。 JavaScript で効果的な非同期コードを作成するには、この概念をしっかりと理解することが不可欠です。

次は何ですか?この記事では Promises/A の仕様全體をカバーしていないため、殘りの部分を?qū)g裝して理解を深めてください。

ここまで読んでいただいたので、楽しんで読んでいただければ幸いです。記事をシェアしてください。

フォローしてください:
LinkedIn、Medium、Github

以上がJavaScript で獨(dú)自の Promise を作成するの詳細(xì)內(nèi)容です。詳細(xì)については、PHP 中國(guó)語(yǔ) Web サイトの他の関連記事を參照してください。

このウェブサイトの聲明
この記事の內(nèi)容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰屬します。このサイトは、それに相當(dāng)する法的責(zé)任を負(fù)いません。盜作または侵害の疑いのあるコンテンツを見(jiàn)つけた場(chǎng)合は、admin@php.cn までご連絡(luò)ください。

ホットAIツール

Undress AI Tool

Undress AI Tool

脫衣畫(huà)像を無(wú)料で

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード寫(xiě)真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

寫(xiě)真から衣服を削除するオンライン AI ツール。

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無(wú)料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡(jiǎn)単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無(wú)料のコードエディター

SublimeText3 中國(guó)語(yǔ)版

SublimeText3 中國(guó)語(yǔ)版

中國(guó)語(yǔ)版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強(qiáng)力な PHP 統(tǒng)合開(kāi)発環(huán)境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開(kāi)発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Java vs. JavaScript:混亂を解消します Java vs. JavaScript:混亂を解消します Jun 20, 2025 am 12:27 AM

JavaとJavaScriptは異なるプログラミング言語(yǔ)であり、それぞれ異なるアプリケーションシナリオに適しています。 Javaは大規(guī)模なエンタープライズおよびモバイルアプリケーション開(kāi)発に使用されますが、JavaScriptは主にWebページ開(kāi)発に使用されます。

JavaScriptコメント:短い説明 JavaScriptコメント:短い説明 Jun 19, 2025 am 12:40 AM

JavaScriptcommentsEareEssentialential-formaining、およびGuidingCodeexecution.1)single-linecommentseared forquickexplanations.2)多LinecommentsexplaincomplexlogiCorprovidededocumentation.3)clarifyspartsofcode.bestpractic

JSで日付と時(shí)間を操作する方法は? JSで日付と時(shí)間を操作する方法は? Jul 01, 2025 am 01:27 AM

JavaScriptで日付と時(shí)間を処理する場(chǎng)合は、次の點(diǎn)に注意する必要があります。1。日付オブジェクトを作成するには多くの方法があります。 ISO形式の文字列を使用して、互換性を確保することをお?jiǎng)幛幛筏蓼埂?2。時(shí)間情報(bào)を取得および設(shè)定して、メソッドを設(shè)定でき、月は0から始まることに注意してください。 3.手動(dòng)でのフォーマット日付には文字列が必要であり、サードパーティライブラリも使用できます。 4.ルクソンなどのタイムゾーンをサポートするライブラリを使用することをお?jiǎng)幛幛筏蓼?。これらの重要なポイントを?xí)得すると、一般的な間違いを効果的に回避できます。

なぜの下部にタグを配置する必要があるのですか? なぜの下部にタグを配置する必要があるのですか? Jul 02, 2025 am 01:22 AM

PLACSTHETTHETTHE BOTTOMOFABLOGPOSTORWEBPAGESERVESPAGESPORCICALPURPOSESESFORSEO、userexperience、andDesign.1.IthelpswithiobyAllowingseNStoAccessKeysword-relevanttagwithtagwithtagwithtagwithemaincontent.2.iTimrovesexperiencebyepingepintepepinedeeping

JavaScript vs. Java:開(kāi)発者向けの包括的な比較 JavaScript vs. Java:開(kāi)発者向けの包括的な比較 Jun 20, 2025 am 12:21 AM

javascriptispreferredforwebdevelopment、whilejavaisbetterforlge-scalebackendsystemsandroidapps.1)javascriptexcelsininintingtivewebexperiences withitsdynAmicnature anddommanipulation.2)javaofferstruntypyping-dobject-reientedpeatures

JavaScript:効率的なコーディングのためのデータ型の調(diào)査 JavaScript:効率的なコーディングのためのデータ型の調(diào)査 Jun 20, 2025 am 12:46 AM

javascripthassevenfundamentaldatypes:number、string、boolean、undefined、null、object、andsymbol.1)numberseadouble-precisionformat、有用であるため、有用性の高いものであるため、but-for-loating-pointarithmetic.2)ストリングリムムット、使用率が有用であること

DOMでのイベントの泡立ちとキャプチャとは何ですか? DOMでのイベントの泡立ちとキャプチャとは何ですか? Jul 02, 2025 am 01:19 AM

イベントキャプチャとバブルは、DOMのイベント伝播の2つの段階です。キャプチャは最上層からターゲット要素までであり、バブルはターゲット要素から上層までです。 1.イベントキャプチャは、AddEventListenerのUseCaptureパラメーターをTrueに設(shè)定することにより実裝されます。 2。イベントバブルはデフォルトの動(dòng)作であり、UseCaptureはfalseに設(shè)定されているか、省略されます。 3。イベントの伝播を使用して、イベントの伝播を防ぐことができます。 4.イベントバブルは、動(dòng)的なコンテンツ処理効率を改善するためにイベント委任をサポートします。 5.キャプチャを使用して、ロギングやエラー処理など、事前にイベントを傍受できます。これらの2つのフェーズを理解することは、タイミングとJavaScriptがユーザー操作にどのように反応するかを正確に制御するのに役立ちます。

JavaとJavaScriptの違いは何ですか? JavaとJavaScriptの違いは何ですか? Jun 17, 2025 am 09:17 AM

JavaとJavaScriptは、異なるプログラミング言語(yǔ)です。 1.Javaは、エンタープライズアプリケーションや大規(guī)模なシステムに適した、靜的に型付けされ、コンパイルされた言語(yǔ)です。 2。JavaScriptは動(dòng)的なタイプと解釈された言語(yǔ)であり、主にWebインタラクションとフロントエンド開(kāi)発に使用されます。

See all articles