1. ホーム
  2. javascript

[解決済み] NodeJS - setTimeout(fn,0) vs setImmediate(fn)

2022-12-08 19:57:41

質問

この2つの違いは何ですか?また、どのような場合にどちらを使うのでしょうか?

どのように解決するのですか?

setTimeout は、単に遅延が終了した後に関数を呼び出すようなものです。関数が呼ばれるときはいつでも、それはすぐに実行されませんが、実行中で、現在キューに入っているすべてのeventhandlerが最初に終了した後に実行されるようにキューに入れられます。それがどれくらい長くかかるかについての保証はありません。

setImmediate は、関数のキューを使わないことを除けば、この点で似ています。それはI/Oイベントハンドラのキューをチェックします。もし現在のスナップショット内のすべてのI/Oイベントが処理されたなら、コールバックを実行します。これは、process.nextTickのように、最後のI/Oハンドラの直後にそれらをキューに入れます。だから、より高速です。

また、(setTimeout,0)は実行前に少なくとも一度はタイマーをチェックするため、遅くなります。時には2倍遅くなることもあります。以下はベンチマークです。

var Suite = require('benchmark').Suite
var fs = require('fs')

var suite = new Suite

suite.add('deffered.resolve()', function(deferred) {
  deferred.resolve()
}, {defer: true})

suite.add('setImmediate()', function(deferred) {
  setImmediate(function() {
    deferred.resolve()
  })
}, {defer: true})

suite.add('setTimeout(,0)', function(deferred) {
  setTimeout(function() {
    deferred.resolve()
  },0)
}, {defer: true})

suite
.on('cycle', function(event) {
  console.log(String(event.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
.run({async: true})

出力

deffered.resolve() x 993 ops/sec ±0.67% (22 runs sampled)
setImmediate() x 914 ops/sec ±2.48% (57 runs sampled)
setTimeout(,0) x 445 ops/sec ±2.79% (82 runs sampled)

最初のものは、最速の呼び出しのアイデアを提供します。setTimeoutが他の半分の回数呼ばれるかどうか、自分で確認することができます。また、setImmediateはファイルシステムの呼び出しに応じて調整されることを忘れないでください。そのため、負荷がかかるとパフォーマンスが低下します。私は、setTimeoutがより良いことができるとは思わない。

setTimeoutは、ある時間経過後に関数を呼び出すための邪魔にならない方法です。ちょうどブラウザにあるようなものです。サーバーサイドには向かないかもしれません(なぜ私がsetTimeoutではなくbenchmark.jsを使用したかを考えてみてください)。