JavaScript の setTimeout と setInterval は、呼び出されるとあらかじめ決められた方法で実行されると思われがちなので、
[javascript] のように、他の人の感情を簡単に欺くことができるメソッドです。
setTimeout(function(){alert('Hello!'); } , 0);
setInterval(callbackFunction , 100);
setTimeout(function(){alert('Hello!'); } , 0); ( callbackFunction , 100);
これは何も考えずに言われたものではなく、JavaScript API ドキュメントで 2 番目のパラメーターの意味が、ここで 0 ミリ秒に設定すると、当然すぐに実行されます。同様に、setInterval の callbackFunction メソッドも 100 秒ごとに即時に実行されます。
しかし、JavaScript アプリケーションの開発経験が増え続け、リッチになったある日、次のような奇妙なコードを見つけました。
};
div.onclick = function(){setTimeout( function(){document.getElementById('inputField) ').focus();}, 0);
};
0 ミリ秒後に実行されるのに、なぜ setTimeout を使用するのでしょうか? この時点で、あなたの確固たる信念が揺らぎ始めました。
最後の日まで、誤って悪いコードを書いてしまいました:
[javascript]
setTimeout( function(){ warning('Hello!'); } , 200 );
setInterval( callbackFunction , 200);
setTimeout( function(){ warning('Hello!'); } , 200); ( callbackFunction , 200);
コードの最初の行 無限ループに入りますが、すぐに 2 行目と 3 行目が期待したものではなく、警告メッセージが表示されず、からのニュースがないことがわかります。 callbacKFunction!
現時点では、あなたはこの状況を受け入れるのが難しいです。長年確立された認識を変えて新しいアイデアを受け入れるプロセスは苦痛ですが、事実は私たちの目の前にあり、 JavaScript の真実は痛みを理由に止まらない JavaScript のスレッドとタイマー探求の旅を広げましょう
雲を開けて月明かりを見てください www.2cto.com
JavaScript エンジンは、ブラウザーがどこにあるかに関係なく、単一のスレッドで実行されます。 JavaScript プログラムを実行するスレッドは常に 1 つだけです。
JavaScript エンジンを単一のスレッドで実行することも理にかなっています。スレッドは、スレッドの同期などの複雑な問題を気にする必要がなく、問題が単純化されます。
それでは、これらのタイマーを処理し、ブラウザのイベントに応答するために、ブラウザ カーネルと連携する方法とは何でしょうか?以下は、ブラウザ カーネルの処理方法に基づいて簡単に説明します。
ブラウザ カーネルの実装では、複数のスレッドが非同期で実行でき、これらのスレッドは、特定の実装の場合、同期を維持します。ブラウザ カーネルには少なくとも 3 つの常駐スレッドがあります: JavaScript エンジン スレッド、インターフェイス レンダリング スレッド、ブラウザ イベント トリガー スレッド。これらに加えて、HTTP リクエスト スレッドなど、実行後に終了するいくつかのスレッドもあります。これらの非同期スレッドは、別の非同期スレッドを生成します。次の図は、シングルスレッド JavaScript エンジンがどのように他のスレッドと対話し、通信するかを示しています。各ブラウザー カーネルの実装の詳細は異なりますが、呼び出し原理は似ています。
JavaScript の setTimeout と setInterval は、他の人の感情を簡単に欺くことができます。なぜなら、呼び出されると、確立された方法で実行されると考えているからです。たとえば、
写真からわかるように、JavaScript は同じように感じていると思います。ブラウザーのエンジンはイベント駆動型です。ここでのイベントは、ブラウザーによって割り当てられたさまざまなタスクとみなすことができます。たとえば、タスクを追加するために setTimeout を呼び出すと、これらのタスクは現在実行されているコード ブロックから発生する可能性があります。また、インターフェイス要素のマウス クリック イベント、スケジュールされたトリガー時刻の到着通知、非同期リクエスト ステータスの変更通知など、ブラウザ カーネルの他のスレッドからも来ます。コードの観点から見ると、タスク エンティティはさまざまなコールバック関数であり、JavaScript エンジンは次のようになります。タスク キュー内のタスクの到着を待っています。単一スレッドの関係により、これらのタスクはキューに入れられ、エンジンによって次々に処理される必要があります
上の図 t1 ~ t2..tn は、異なる時点を表しています。小さな四角はその時点のタスクを表し、時刻 t1 でエンジンが t1 に対応するタスク ブロック コードで実行されているとします。この時点での他のスレッドのステータスを説明します。ブラウザカーネル内:
T1 時間:
GUI レンダリング スレッド:
このスレッドは、ブラウザ インターフェイスの HTML 要素のレンダリングを担当します。このスレッドは、インターフェイスの再描画 (再描画) が必要な場合、または何らかの操作によってリフローが発生した場合に実行されます。ただし、この記事では JavaScript のタイミング メカニズムについて説明します。現時点ではこれが必要です。レンダリング スレッドについて説明します。このスレッドは JavaScript エンジン スレッドと相互に排他的であるため、JavaScript スクリプトはこれらの要素のプロパティを変更してレンダリングすることができるため、これは簡単に理解できます。
JavaScript エンジンがスクリプトを実行している間、ブラウザのレンダリング スレッドは一時停止状態、つまり「フリーズ」状態になります。
そのため、スクリプト内でノードの追加などのインターフェースを更新しても、ノードの削除やノードの外観の変更などの更新はすぐには反映されません。これらの操作はキューに保存され、JavaScript の実行時にレンダリングされます。エンジンはアイドル状態です。 GUI イベント トリガー スレッド: JavaScript スクリプト t1 期間では、ユーザーが最初にマウス ボタンをクリックすると、そのクリックがブラウザーのイベント トリガーによってキャプチャされます。図からわかるように、JavaScript エンジン スレッドの場合、このイベントは他のスレッドによってタスク キューの最後に非同期的に送信されます。これは、エンジンが t1 でタスクを処理しているためです。クリック イベントは処理を待機しています。タイミング トリガー スレッド:ここでのブラウザ モデルのタイミング カウンターは、ブロックされたスレッド内にある場合、JavaScript エンジンによってカウントされることに注意してください。JavaScript エンジンはシングルスレッドであるためです。状態では、時間をカウントすることはできません。タイミングを計ってトリガーするために外部に依存する必要があるため、キュー内のタイミング イベントも非同期イベントです。写真からわかるように、この t1 期間中は、その後マウス クリック イベントがトリガーされると、以前に設定された setTimeout タイミングも到着します。このとき、JavaScript エンジンの場合、タイミング トリガー スレッドは非同期タイミング イベントを生成し、このイベントがクリック後にキューに入れられます。イベントコールバック、処理待ちです同様に、まだt1期間内ですが、一定のsetIntervalタイマーも追加されていますので、t1期間中に2回連続でトリガーされます。
[javascript]
setTimeout(function(){
) /* コード ブロック... */
setTimeout(arguments.callee,
}, 10);
setInterval(function (){
/* コード ブロック... */
}, 10); ;
setTimeout(function(){
/* コードブロック... */
setTimeout(arguments.callee, 10);
}, 10 );
/* コードブロック... */
}, 10);
実際、リクエストは確かに非同期ですが、このリクエストは新しいものです。ブラウザーによって開かれたスレッド (上の図を参照)、リクエストのステータスが変更されると、コールバックが事前に設定されている場合、非同期スレッドはステータス変更イベントを生成し、JavaScript エンジンの処理キューに入れます。タスクが処理されるとき、JavaScript エンジンは常にシングルです。スレッドはコールバック関数を実行します。具体的には、onreadystatechange で実行されるシングルスレッドによって設定された関数です。