4

setTimeout の解決に問題がありました。50 ミリ秒に設定すると、51 ミリ秒から 80 ミリ秒まで変化します。sleep モジュールを使用すると、50 µs のような解像度を得ることができます。それを修正/回避する方法はありますか? スリープの問題は、コールバック関数を発射する必要がある場合でも、すべてを遅延させることです... 正確に 50 ミリ秒の遅延でいくつかのイベントを発射する別の解決策はありますか?

たとえば、sleep モジュールの場合:

var start = new Date().getTime();
sleep.usleep(50);
console.log(new Date().getTime() - start);`

結果は 0 です。マイクロタイムは 51 ~ 57 µs です。それで一体何?

4

3 に答える 3

2

setTimeout ドキュメントから:

コールバックは正確に遅延ミリ秒で呼び出されない可能性が高いことに注意することが重要です。

遅延の精度は、コード ブロックがどれだけ小さいかによって決まります。つまり、コードが持つ単一のスレッドで多くの操作を実行するsetTimeoutと、多くの遅延でトリガーされる可能性があります。反対に、それはほぼ正確になります。

あなたは自分で違いを見ることができました、これを実行してください

var start = Date.now();
setTimeout(function() { console.log(Date.now() - start); }, 500);
for(var i=0; i<999999999; ++i){}

// 1237ms

これとの違いに注意してください:

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

// 507ms
于 2013-08-19T15:46:45.650 に答える
0

そのため、setTimeout のようなもので可能な限り最高のタイム レートを達成するために、特定のモジュールのイベント ループをできるだけ小さく保ちたいと考えています。これにより、V8 エンジンがループの処理に費やす時間が最小限に抑えられます。最良のシナリオ:

setInterval(function(){}, 50);

これがファイル内の唯一のものである場合、他に何も行われていないため、精度は非常に高くなります。SO、私たちがしていることは、この間隔で行いたい作業のみを行う特定のモジュールのプロセスをフォークすることです。関数内の唯一のものが非同期リクエストである場合、それは上記と同じくらい良いです。そのため、setInterval 関数で非常に高いレベルの精度が得られます。

1 つのファイルに次の内容が必要です。これを file1.js と呼びます。

var http = require('http');

var options = {
    hostname: 'localhost',
    port: 8888,
    path:'/',
    method: 'GET'
}

setInterval(function(){
    console.log('File:' + (new Date).getTime() % 50);
    //The Modulus of the time in MS should change by no more than 1 MS on consecutive runs, I confirmed this works just dandy on my system(though the first couple intervals were slower in some instances, worse I saw was a 3 MS delay)
    var req = http.request(options, function (res) {
        res.on('data', function (data) {
            console.log(data.toString());
        });
    });

    req.end();
}, 50);

2 番目のファイルでは、実際に必要な作業が何であれ、より多くの作業を行うことができます。重要なことは、OWN PROCESS 内に含まれる上記の作業を行うプロセスを生成することです。これにより、プロセス V8 プロセッサがこのイベント ループを非常に小さく保つことができます。CPU 上の特定のプロセスのオペレーティング システム管理の被害者のままですが、file1.js モジュールが少なくとも 1 ミリ秒ごとに注意を引くことを期待できます。次に上記の非同期呼び出しを開始する必要があるとき、呼び出し間の最大の遅延は 1 ミリ秒です (少なくとも、システムで見たのはそれだけです)。したがって、もう一方のファイルには任意の量の作業を含めることができ、非常に重要な 1 行を含めることができます。

file2.js:

var http = require('http');
var child_process = require('child_process');


http.createServer(function (req, res) {
    res.write('Hi There');
    res.end();
}).listen(8888);

///Do whatever else you need to do

child_process.fork('file1.js');//Add in this line!!!!

期待される出力:

File:29
Hi There
File:29
Hi There
File:30//Notice these values only increase by 0 or 1.  
Hi There
File:31
Hi There
File:31
Hi There
File:32
Hi There
File:34//Uh oh, one went up by 2... not terrible
Hi There
File:35
Hi There
File:35
于 2013-08-19T15:51:14.690 に答える