2012-02-17 19 views
4

次のコードはProject Silk(マイクロソフトのサンプルアプリケーション)から取得したものです 以下のpublishメソッドは、イベントcallBacksの配列をループし、それぞれを実行します。 forループを使用する代わりに、代わりにsetIntervalが使用されます。setIntervalを使用して関数を非同期で呼び出すことはできますか?

これにより、前回のコールバックが完了する前に、各加入者コールバックを呼び出すことができるようになりました。これは正しいです?私は、インターバル内の関数の実行が、その前のすべての実行が終了するまで、ブラウザが実行することを許可しないと考えました。

これはforループを実行することとはまったく異なりますか?

that.publish = function (eventName, data) 
{ 
    var context, intervalId, idx = 0; 
    if (queue[eventName]) 
    { 
     intervalId = setInterval(function() 
     { 
      if (queue[eventName][idx]) 
      { 
       context = queue[eventName][idx].context || this; 
       queue[eventName][idx].callback.call(context, data); 
       idx += 1; 
      } 
      else { clearInterval(intervalId); } 
     }, 0); 
    } 
+0

http://ejohn.org/blog/how-javascript-timers-work/は、あなたがこのような何かを探しています:https://github.com/caolan/async#parallel –

+0

このコードはドキュメントはそれがないと主張するものない場合、私は理解に興味があります。なぜなら、何かがあるなら、 'setInterval'が動作する方法について私は理解していないからです。私はそれを理解していない、特にJSはシングルスレッドなので。 –

+2

'setInterval(...、0)'コールバックは、ブラウザが再び制御権を持つまでは起動されないので、 'setInterval'コールは「ブラウザが終了したらこの関数を呼び出す」と言っています。 –

答えて

4

ここで、setIntervalを使用すると、次回のメイン実行スレッドが利用可能になるためにコールバックの実行をスケジュールするため、実行非同期の並べ替えが行われます。

これは、他の同期処理がコールバックの前に実行されるため(コールバックがメイン実行スレッドに余分なミリ秒を持つ場合にのみ実行されるため)、コールバックの実行によってブラウザがブロックされないことを意味します。この構造は通常のforループよりも優れています。つまり、コールバックがブラウザをブロックせず、恐ろしい "このページにはスクリプトが長すぎます"というエラーが発生しません。

このスケジューリングパターンの副作用は、タイムアウトが「示唆」に過ぎないということです。これがここでは0を使用する理由です。

参照:

4

setInterval(..., 0)はあなたのコードが実行に時間がかかる場合、凍結を防止するために、ブラウザのUIに制御を得るために使用することができます。

この場合、that.publishはコールバックが実行される直前に終了します。各コールバックは「バックグラウンドで」実行され、イベントループに配置され、次のコールバックが実行される前に、それぞれのコールバックがブラウザに渡されます。

これは、イベント処理では良い考えです。多くのイベント処理や終了に時間がかかる場合でも、イベント処理によってブラウザがフリーズしないようにするためです。

ドキュメントについて - 記載されているとおり、間違っています。 Javascriptはシングルスレッドです。しかし、publish()を連続して数回呼び出す場合は、setTimeoutのためにコールバックが実行される前にこれらの呼び出しがすべて完了することは真です。おそらく、これはドキュメンテーションが意味するものでしょうか?

関連する問題