ホームページ > 記事 > ウェブフロントエンド > Promise が setTimeout() よりも速い理由の詳細な分析
Promise が setTimeout() より速いのはなぜですか?次の記事ではその理由を分析します。一定の参考値があるので、困っている友達が参考になれば幸いです。
関連する推奨事項: 「JavaScript ビデオ チュートリアル 」
実験をしてみましょう。すぐに解決される Promise と即時 setTimeout
(つまり、setTimeout 0 ミリ秒) のどちらが速く実行されますか?
Promise.resolve(1).then(function resolve() { console.log('Resolved!'); }); setTimeout(function timeout() { console.log('Timed out!'); }, 0); // 'Resolved!' // 'Timed out!'
promise.resolve(1)
はstatic すぐに解決される promise
を返す関数。 setTimeout(callback, 0)
0 ミリ秒
の遅延でコールバック関数を実行します。
最初に 'Resolved!'
が出力され、次に Timeout completed!
が出力されることがわかります。すぐに解決される Promise は、即時 setTimeout
。
は、Promise.resolve(true).then(...)
が setTimeout(..., 0)
より前に呼び出されたため、Promise プロセスはもっと速いですか?公正な質問です。
それでは、実験条件を少し変更して、setTimeout(..., 0)
:
setTimeout(function timeout() { console.log('Timed out!'); }, 0); Promise.resolve(1).then(function resolve() { console.log('Resolved!'); }); // 'Resolved!' // 'Timed out!'
setTimeout(..., 0) を呼び出してみましょう。 )
は Promise.resolve(true).then(...)
の前に呼び出されます。ただし、Resolved!
が最初に出力され、次に 'Timed out!'
が出力されます。 ######どうしてこれなの?
[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-Lt9zVHTf-1611275604640)(/img/bVcMQaI)]
Call stackは、コードの実行中に作成された実行コンテキストを格納する LIFO (後入れ先出し) 構造です。簡単に言えば、コール スタックはこれらの関数を実行します。 Web API では、非同期操作 (フェッチ リクエスト、プロミス、タイマー) とそのコールバックが完了を待機します。
**タスク キュー (タスク キュー)
は、実行準備ができている非同期操作のコールバックを保存するFIFO (先入れ先出し)** 構造です。たとえば、タイムアウトした setTimeout() のコールバック関数や、実行準備ができたクリック ボタン イベント ハンドラは、タスク キューにキューイングされます。 **ジョブ キュー (ジョブ キュー)** は FIFO (先入れ先出し) 構造で、実行準備が整った
のコールバックを保存します。たとえば、完了した Promise の resolve
または reject
コールバックはジョブ キューに入れられます。 最後に、イベント ループはコール スタックが空かどうかを永続的に監視します。コール スタックが空の場合、イベント ループはジョブ キューまたはタスク キューを調べ、実行の準備ができているコールバックをコール スタックにディスパッチします。
A) コール スタックは
setTimeout(..., 0) を実行し、タイマー timeout()
をスケジュールします。コールバックは Web API に保存されます。
[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-SLk0AUa5-1611275604642)(/img/bVcMQdg)]
[外部リンク画像 転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-Zr7usYTK-1611275604643)(/img/bVcMQc9)]
B) スタック実行を呼び出します
Promise.resolve (true).then(resolve)そして promise
ソリューションを手配します。 resolved()
コールバックは Web API に保存されます: [外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムが備わっている可能性があります。画像を保存することをお勧めします。直接アップロードしてください (img-JTwSnLYS- 1611275604646)(/img/bVcMQdh)]
[外部リンク画像の転送に失敗しました。ソース サイトにはホットリンク対策メカニズムがある可能性があります。画像を保存することをお勧めします。直接アップロードしてください (img-k5cRhqzN-1611275604648)(/img/bVcMQdi )]
C) Promise はすぐに解決され、タイマーはすぐに実行されます。このようにして、タイマー コールバック
timeout() がタスク キューに入り、promise
コールバック resolve()
がジョブ キュー に入ります。 [外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムが組み込まれている可能性があります。画像を保存して直接アップロードすることをお勧めします (img-iMfLB2YJ-1611275604649)(/img/bVcMQdS)]
D ) ここからが興味深い部分です。ジョブ キュー (マイクロタスク) ) はタスク キュー (マクロ タスク) よりも高い優先順位を持っています。イベント ループは、ジョブ キューから Promise コールバック
resolve() を取得し、コール スタックに入れます。次に、コール スタックは Promise コールバック resolve()
: [外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムが組み込まれている可能性があります。画像を作成して直接アップロードします (img-nnqfgoo1 -1611275604650)(/img/bVcMQey)]
E) 最後に、イベント ループはタイマー コールバック
timeout() をタスク キューからデキューします。呼び出しスタック。次に、コール スタックはタイマー コールバック timeout()
: [外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムが備わっている可能性があります。画像を作成して直接アップロードします (img- Fj54WaI0-1611275604650)(/img/bVcMQeB)]
呼び出しスタックは空で、スクリプトの実行は完了しました。
即時解決された Promise が即時実行タイマーよりも速く処理されるのはなぜですか?
イベント ループの優先順位が存在するため、タスク キュー (タイムアウトの setTimeout()
コールバックを保存する) と比較して、ジョブ キュー (実装された Promise# を保存する) ##Callback) の方が優先されます。
元のアドレス: https://dmitripavlutin.com/javascript-promises-settimeout/著者: Milos Protic翻訳アドレス: https://segmentfault .com/a/1190000038769853コンピューター プログラミング関連の知識の詳細については、
プログラミング ビデオ をご覧ください。 !
以上がPromise が setTimeout() よりも速い理由の詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。