2011-08-28 13 views
34

ブラウザでは、setTimeoutという関数内からsetTimeoutを使用すると、4msの最小遅延が強制されます。 Mozillaの開発者向けのwiki describes this behaviourで、become standardized in HTML5と書かれています。Node.jsはsetTimeoutの最小遅延を強制しますか?

Node.jsのdocumentation for setTimeoutには最小遅延はありません。しかし、the process.nextTick functionのドキュメントでは、setTimeout(fn, 0)のより効率的な代替手段として記述されています。これは、この遅延を回避しているため、より効率的である可能性を示唆しています。そうでなければsetTimeout(fn, 0)はおそらく同じように動作するように最適化できます。

Node.jsはウェブブラウザと同様にsetTimeoutの最小遅延を強制しますか?

答えて

17

これは、遅延が最小ではなく、実際にはブラウザとノードの間の互換性の問題です。タイマーはJavaScriptで完全には特定されていません(Node仕様を使用していて、ブラウザでも使用されていないDOM仕様です)。ノードは、JavaScriptの歴史にどのように根本的なものか、

ノードは、ファイルシステムやネットワークなどの低レベルシステムのためのクロスプラットフォームの抽象化レイヤーであるlibuvを使用します。その1つはタイマーであり、Nodeは最小のラッパーを提供します。 libuvレベルでは、使用されるタイマーはシステム固有の高精度タイマーです。たとえば、Windowsの場合、これは、ナノ秒単位で測定される解像度を提供するQueryPerformanceFrequencyおよびFileTimeToSystemTimeを使用して実装されます。

ノードでは、setTimeout(callback, 1)を指定した場合、1ミリ秒後に実行されます(システムが圧倒的に遅れないと仮定した場合)。ブラウザでは、最小時間はHTML5仕様:https://developer.mozilla.org/en/DOM/window.setTimeoutで指定されているように4ミリ秒になります。これは保証された時間ではなく、最低限のものです。ほとんどのブラウザは、DOMアニメーションに影響する〜15msの解像度を持つと予想されます。

有効な情報は、同じフレーム内で同じミリ秒に設定されたタイムアウトが、キューに入れられた順に実行されることです。あなたがするべきだったら:

setTimeout(callback1, 1); 
    setTimeout(callback2, 1); 
    setTimeout(callback3, 1); 
    setTimeout(callback4, 1); 

すべてが1ブロックで、Nodeはそれらをこの順に呼び出す必要があります。これは、解決時間がまったく同じ場合にのみ適用されます。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724280(v=vs.85).aspx

15

このテストでは、最小遅延がないように見えます。

あなたは10ms期間、およびコンソールへの長い戻り値を持つsetTimeout()が、これはあなたが得るものです行う場合:

var timer = setTimeout(function(){ console.log(timer);}, 10); 

{ _idleTimeout: 10, 
    _onTimeout: [Function], 
    _idlePrev: null, 
    _idleNext: null, 
    _idleStart: Sun, 28 Aug 2011 14:34:41 GMT } 

同様に、1ms期間で、あなたが得る:

var timer = setTimeout(function(){ console.log(timer);}, 1); 

{ _idleTimeout: 1, 
    _onTimeout: [Function], 
    _idlePrev: null, 
    _idleNext: null, 
    _idleStart: Sun, 28 Aug 2011 14:34:59 GMT } 

しかし、0の期間を実行すると、_idleTimeout:プロパティがまったく取得されないため、コールバックが非同期ではすぐに呼び出されることが示唆されます。私は、単純な開始/終了日付の比較を行う場合

var timer = setTimeout(function(){ console.log(timer);}, 0); 

{ repeat: 0, callback: [Function] } 

さらに、私は通常端からスタートを引いた結果として0を得る

var start = Date.now(); 
var timer = setTimeout(function(){ console.log(timer, Date.now() - start);}, 0); 

{ repeat: 0, callback: [Function] } 0 

これらの試験は、Node.js 0.5.2を用いて行った。

1

タイマの実装はオペレーティングシステムによって異なります。例えば、私は、タイマーの解像度がWindowsでは16ms、他のプラットフォームでは1msだった "良い古い" JTimerの問題を覚えています。特定のサーバーでテストする価値はほとんどあります。

関連する問題