NodeJS - setTimeout(fn,0) vs setImmediate(fn)
这两者之间有什么区别,我什么时候会使用一个而不是另一个?
这两者之间有什么区别,我什么时候会使用一个而不是另一个?
setTimeout 就像在延迟完成后调用函数一样。每当调用函数时,它都不会立即执行,而是排队,以便在所有正在执行和当前排队的事件处理程序首先完成之后执行该函数。setTimeout(,0) 本质上意味着在执行当前队列中的所有当前函数后执行。不能保证可能需要多长时间。
setImmediate在这方面是相似的,除了它不使用函数队列。它检查 I/O 事件处理程序的队列。如果当前快照中的所有 I/O 事件都已处理完毕,则执行回调。它在最后一个 I/O 处理程序之后立即将它们排队,有点像 process.nextTick。所以它更快。
此外(setTimeout,0)会很慢,因为它在执行之前至少会检查计时器一次。有时它可能会慢两倍。这是一个基准。
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 是一段时间后调用函数的非侵入性方式。就像它在浏览器中一样。它可能不适合服务器端(想想为什么我使用基准测试.js而不是setTimeout)。
一篇关于事件循环如何工作的好文章,并清除了一些误解。http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/
引用文章:
setImmediate
回调是在 I/O 队列回调完成或超时后调用的。set直接回调放置在检查队列中,这些回调在 I/O 队列之后进行处理。
setTimeout(fn, 0)
回调放置在定时队列中,并将在 I/O 回调以及检查队列回调之后调用。作为事件循环,在每次迭代中首先处理计时器队列,因此首先执行哪一个取决于事件循环的阶段。