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)
(但我甚至不能想象,为什么)。 setImmediate
callback将几乎总是在setTimeout(,0)
之前执行,除非在第一个tick和setImmediate
callback中setImmediate
调用。
关于事件循环是如何工作的一篇很好的文章,并澄清了一些误解。 http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/
引用文章:
setImmediate
callback在I / O队列callback完成或超时后调用。 setImmediatecallback放置在Check Queue中,在I / O Queue之后处理。
setTimeout(fn, 0)
callback被放置在定时器队列中,将在I / Ocallback以及Check Queuecallback之后被调用。 作为事件循环,首先在每个迭代中处理定时器队列,那么哪一个将首先执行取决于哪个阶段的事件循环。
使用setImmediate()不阻塞事件循环。 callback将在下一个事件循环中运行,只要当前循环完成。
使用setTimeout()来控制延迟。 该function将在指定的延迟之后运行。 最小延迟是1毫秒。