NodeJS – setTimeout(fn,0)vs setImmediate(fn)

这两者之间有什么区别,我什么时候可以使用一个呢?

setTimeout就像延迟结束后调用函数一样。 每当一个函数被调用时,它不会立即执行,而是排队,以便在所有执行和当前排队的事件处理程序完成之后执行。 setTimeout(,0)本质上是指当前队列中所有当前函数执行后执行。 不能保证可能需要多长时间。

setImmediate在这方面是类似的,只是它不使用函数队列。 它检查I / O事件处理程序的队列。 如果处理当前快照中的所有I / O事件,则执行callback。 它在最后一个I / O处理程序(像process.nextTick)之后直接排队。 所以它更快。

另外(setTimeout,0)会很慢,因为它在执行之前至less要检查一次定时器。 有时它可能会慢一倍。 这是一个基准。

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将适应您的文件系统调用。 所以在负载下它会执行得更less。 我不认为setTimeout可以做得更好。

setTimeout是一段时间后调用函数的非侵入性方式。 它就像它在浏览器中一样。 它可能不适合服务器端(想想为什么我使用benchmark.js不setTimeout)。

setImmediate()用于在I / O事件callback之后和setTimeout和setInterval之前计划立即执行callback。

setTimeout()是在延迟毫秒后计划执行一次性callback。

这是文件说的。

 setTimeout(function() { console.log('setTimeout') }, 0) setImmediate(function() { console.log('setImmediate') }) 

如果你运行上面的代码,结果将是这样的…即使当前的文档指出:“安排在I / O事件callback之后和setTimeout和setInterval之前的”立即“执行callback。 ..

结果..

的setTimeout

setImmediate

如果你把你的例子包装在另一个计时器中,它总是打印setImmediate,然后是setTimeout。

 setTimeout(function() { setTimeout(function() { console.log('setTimeout') }, 0); setImmediate(function() { console.log('setImmediate') }); }, 10); 

总是使用setImmediate ,除非你真的确定你需要setTimeout(,0) (但我甚至不能想象,为什么)。 setImmediatecallback将几乎总是在setTimeout(,0)之前执行,除非在第一个tick和setImmediatecallback中setImmediate调用。

关于事件循环是如何工作的一篇很好的文章,并澄清了一些误解。 http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/

引用文章:

setImmediatecallback在I / O队列callback完成或超时后调用。 setImmediatecallback放置在Check Queue中,在I / O Queue之后处理。

setTimeout(fn, 0)callback被放置在定时器队列中,将在I / Ocallback以及Check Queuecallback之后被调用。 作为事件循环,首先在每个迭代中处理定时器队列,那么哪一个将首先执行取决于哪个阶段的事件循环。

使用setImmediate()不阻塞事件循环。 callback将在下一个事件循环中运行,只要当前循环完成。

使用setTimeout()来控制延迟。 该function将在指定的延迟之后运行。 最小延迟是1毫秒。