JavaScriptのピットのシングルスレッド
1963 ワード
下のコメントを見て、jsのスレッドが分かりました.以前はスレッドについてあまり知らなかったので、この機会にスレッドの知識を整理しておきます.
JSはブラウザで実行していますので、単一スレッドです.つまり、各windowにJSスレッドがあります.単一スレッドはプログラム実行時に、歩いているプログラムパスを連続順に並べて、前のものは必ず処理して、後のものは実行します.ブラウザはイベントドライバであり、ブラウザでは非同期的な行動が多く、イベントを作成して実行キューに入れます.JSのエンジンはシングルスレッドでそのタスクを処理するキューであり、成果は通常関数とコールバック関数で構成されるキューであることが理解できます.非同期イベントが発生した場合、例えばmouse click、a timer firing、or an XMLtRequest completteing(XMLtpRequest完了レギュレータなど)を実行キューに入れ、現在のコードの実行が完了するのを待つ.
非同期イベント駆動
ブラウザはイベント駆動ですが、非同期的な行動も多いです.非同期イベントが発生すると、それはイベントキューに入ります.例えばsetTimeoutは、呼出すると、jsエンジンがタイマーtimerを起動し、約xms後にxxxを実行し、タイマーの時間が来たら、このイベントをメインイベントキューに置いて処理を待つ(ブラウザが忙しくない時に実行される).
set Timeout実行原理
set Timeoutの時間遅延は保証されない.例えば、setTimeout(fn,500)は、fnが500ミリ秒後にすぐに実行されるとは限らず、遅延がより長くなる可能性が高い.
16.7 ms
DELAY:|------------|CLOCK:|--------|--------|
15.6 ms 15.6 ms
IE 8およびそれ以前のIEバージョンの更新間隔は15.6ミリ秒である.設定されたsetTimeoutが16.7 msに遅延したとすると、2つの15.6ミリ秒を更新しなければならない.これはまた、理由なしに15.6 x 2−16.7=14.5ミリ秒の遅延を意味する.
したがって、セットTimeoutに設定した遅延が0 msであっても、すぐにトリガしません.たとえtimer resolutionが16.7 msに達することができたとしても、それはまだ非同期の行列の問題に直面しています.非同期の関係でsetTimeoutのコールバック関数はすぐに実行されるのではなく、待ち行列に参加する必要があるからです.しかし問題は、遅延トリガを待つ間に、新しい同期スクリプトが実行される必要がある場合、同期スクリプトは、timerのフィードバックの後に配置されず、直ちに実行されることである.したがって、setTimeoutのコールバック関数はまだ待ち続けられます.
先ほどの問題に戻ります.一旦二つのコードは違っていません.setTimeoutコール関数の実行と前回の実行との間の間隔は少なくとも10 msあります.(もっと多いかもしれません.待ち行列の中で待っていますが、10 ms以下ではないです.)、setIntervalのコールバック関数は10 msごとに一回実行してみます.前回の実行が完了するかどうかに関わらず.
締め括りをつける JavaScriptエンジンは単一スレッドであり、すべての非同期イベントを強制的にキューに入れて実行を待つ . setTimeoutとset Intervalは、非同期コードを実行する際に根本的な違いを持っています. タイマがブロックされて、すぐに実行できない場合、次の実行可能な時点まで遅延して実行される(所望の時間間隔よりも長い) . setIntervalコールコールコールバック関数の実行時間は、指定された時間間隔よりも十分に長く、連続して実行され、互いに時間間隔がない.
setTimeout(function(){
/* ... */
setTimeout(arguments.callee, 10);
}, 10);
setInterval(function(){
/* ... */
}, 10);
JSはシングルスレッドですJSはブラウザで実行していますので、単一スレッドです.つまり、各windowにJSスレッドがあります.単一スレッドはプログラム実行時に、歩いているプログラムパスを連続順に並べて、前のものは必ず処理して、後のものは実行します.ブラウザはイベントドライバであり、ブラウザでは非同期的な行動が多く、イベントを作成して実行キューに入れます.JSのエンジンはシングルスレッドでそのタスクを処理するキューであり、成果は通常関数とコールバック関数で構成されるキューであることが理解できます.非同期イベントが発生した場合、例えばmouse click、a timer firing、or an XMLtRequest completteing(XMLtpRequest完了レギュレータなど)を実行キューに入れ、現在のコードの実行が完了するのを待つ.
非同期イベント駆動
ブラウザはイベント駆動ですが、非同期的な行動も多いです.非同期イベントが発生すると、それはイベントキューに入ります.例えばsetTimeoutは、呼出すると、jsエンジンがタイマーtimerを起動し、約xms後にxxxを実行し、タイマーの時間が来たら、このイベントをメインイベントキューに置いて処理を待つ(ブラウザが忙しくない時に実行される).
set Timeout実行原理
set Timeoutの時間遅延は保証されない.例えば、setTimeout(fn,500)は、fnが500ミリ秒後にすぐに実行されるとは限らず、遅延がより長くなる可能性が高い.
16.7 ms
DELAY:|------------|CLOCK:|--------|--------|
15.6 ms 15.6 ms
IE 8およびそれ以前のIEバージョンの更新間隔は15.6ミリ秒である.設定されたsetTimeoutが16.7 msに遅延したとすると、2つの15.6ミリ秒を更新しなければならない.これはまた、理由なしに15.6 x 2−16.7=14.5ミリ秒の遅延を意味する.
したがって、セットTimeoutに設定した遅延が0 msであっても、すぐにトリガしません.たとえtimer resolutionが16.7 msに達することができたとしても、それはまだ非同期の行列の問題に直面しています.非同期の関係でsetTimeoutのコールバック関数はすぐに実行されるのではなく、待ち行列に参加する必要があるからです.しかし問題は、遅延トリガを待つ間に、新しい同期スクリプトが実行される必要がある場合、同期スクリプトは、timerのフィードバックの後に配置されず、直ちに実行されることである.したがって、setTimeoutのコールバック関数はまだ待ち続けられます.
先ほどの問題に戻ります.一旦二つのコードは違っていません.setTimeoutコール関数の実行と前回の実行との間の間隔は少なくとも10 msあります.(もっと多いかもしれません.待ち行列の中で待っていますが、10 ms以下ではないです.)、setIntervalのコールバック関数は10 msごとに一回実行してみます.前回の実行が完了するかどうかに関わらず.
締め括りをつける