SetTimeout はあなたが思っているのと同じではありません

WBOY
リリース: 2024-08-06 00:43:01
オリジナル
656 人が閲覧しました

開発者が初めて JavaScript で setTimeout に遭遇したとき、多くの場合、これは関数の実行を遅らせる簡単なツールのように思えます。ただし、setTimeout が JavaScript ランタイムおよびイベント ループとどのように対話するかを理解すると、特に特定の状況で予期しない動作が明らかになる可能性があります。それは setTimeout だけではありません。 setInterval や他の非同期関数でも同様の複雑さが発生します。

イベント ループ: 概要
JavaScript はシングルスレッドです。つまり、一度に 1 つのコードしか実行できません。それにもかかわらず、イベント ループにより、JavaScript はノンブロッキング操作を実行できます。これは、タイマー、ネットワーク リクエスト、I/O 操作などのタスクをブラウザまたは Node.js API にオフロードすることで実現します。これらのタスクが完了すると、コールバック関数は実行のためにイベント ループに再度キューに入れられます。

SetTimeout is Not the Same as You Think

setTimeout の仕組み
setTimeout を呼び出すと、指定された期間の後に関数を実行するように JavaScript エンジンに要求します。これは、イベント ループのキューにコールバック関数を追加することによって行われます。ただし、指定された遅延は、コールバックをキューに追加する前にエンジンが待機する必要がある最小時間であり、保証された実行時間ではありません。詳しい仕組みは次のとおりです:

  1. 初期呼び出し: コールバック関数と遅延を指定して setTimeout が呼び出されると、JavaScript エンジンはこれをブラウザーまたは Node.js が提供する Web API 環境に登録します。

  2. タイマー: Web API は、指定された遅延時間のタイマーを開始します。この期間中、メインの呼び出しスタックは、setTimeout 呼び出しに続く同期コードを実行し続けます。

  3. コールバック キュー: タイマーが期限切れになっても、Web API はコールバックをすぐには実行しません。代わりに、コールバック関数をイベント キューに移動します。

  4. イベント ループ: コール スタックとイベント キューを継続的に監視するイベント ループが機能します。コール スタックが空の場合、つまり現在実行中のタスクがない場合、イベント ループはイベント キューから最初の関数を取得し、それを実行のためにコール スタックにプッシュします。

  5. 実行: コールバック関数は、コール スタックの先頭に到達すると最終的に実行されます。

タイマーが期限切れになったときにコール スタックが他のタスクでビジー状態である場合、コールバック関数が実行されるまでにさらに遅延が発生する可能性があることに注意することが重要です。これは、イベント ループがイベント キューからのコールバック関数を処理する前に、コール スタックがクリアされるまで待機する必要があるためです。

SetTimeout is Not the Same as You Think


ブロックの問題
よくある誤解は、setTimeout が常に指定された正確な遅延時間の後にコールバックを実行すると想定していることです。イベント ループが無限ループや長時間実行の計算などの同期コードによってブロックされている場合、イベント ループが解放されるまでコールバックは実行されません。

次のシナリオを考えてみましょう:

console.log('Program started at: ' + new Date().toLocaleTimeString());

const programStartTime = Date.now();

function blockExecutionForThirtySeconds() {
  while (true) {
    const currentTime = Date.now();
    if (currentTime - programStartTime > 30000) {
      console.log('Blocking execution completed after 30 seconds...');
      return true;
    }
  }
}

console.log('Setting setTimeout for 1 second.');
setTimeout(() => {
  console.log('setTimeout executed after 30 seconds instead of 1 second: ' + new Date().toLocaleTimeString());
}, 1000);

blockExecutionForThirtySeconds();

ログイン後にコピー

この例では、blockExecutionForThirtySeconds 関数が 30 秒間実行される無限ループでイベント ループをブロックします。 setTimeout が 1 秒後に実行されるように設定されている場合でも、blockExecutionForThirtySeconds が完了した後、つまり 30 秒後にのみ実行されます。

SetTimeout is Not the Same as You Think

現実世界への影響
この動作を理解することは、開発者にとって、特にタイムアウト、間隔、または非同期処理を伴うコードを作成する場合には非常に重要です。 setTimeout の仕組みを誤解すると、追跡が困難なパフォーマンスの問題やバグが発生する可能性があります。コードの一部が負荷の高い計算や長時間実行タスクを実行し、イベント ループをブロックした場合、すべての setTimeout コールバック、Promise 解決、およびその他の非同期操作は、イベント ループが解放されるまで遅延されます。

結論
setTimeout は、コードの実行を遅延させるための JavaScript の強力なツールですが、そのニュアンスを理解することが重要です。指定された遅延は、関数が実行のためにキューに入れられるまでに待機する最小時間です。実際の実行時間は、イベント ループの状態によって異なります。非同期操作とイベント ループ管理をマスターすることは、効率的で応答性の高い JavaScript アプリケーションを作成するための鍵となります。

以上がSetTimeout はあなたが思っているのと同じではありませんの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート