两者之间有什么区别,什么时候可以使用另一个?
Answers:
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是一段时间后调用函数的非介入方式。就像在浏览器中一样。它可能不适合服务器端(请考虑为什么我使用Benchmark.js而不使用setTimeout)。
一篇有关事件循环如何工作并清除一些误解的出色文章。 http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/
引用文章:
setImmediate在I / O队列回调完成或超时后调用回调。setImmediate回调放置在Check Queue中,在I / O Queue之后进行处理。
setTimeout(fn, 0)回调被放置在Timer Queue中,并将在I / O回调以及Check Queue回调之后被调用。作为事件循环,在每次迭代中首先处理计时器队列,因此哪个事件将首先执行取决于哪个阶段的事件循环。
setImmediate()用于计划在I / O事件回调之后,setTimeout和setInterval之前立即执行回调。
setTimeout()用于安排在延迟毫秒后执行一次回调。
这就是文件所说的。
setTimeout(function() {
console.log('setTimeout')
}, 0)
setImmediate(function() {
console.log('setImmediate')
})
如果您运行上述代码,即使当前文档指出“要在I / O事件回调之后,setTimeout和setInterval之前安排“立即”执行回调,结果也将是这样。..
结果..
setTimeout
setImmediate
如果将示例包装在另一个计时器中,则它将始终输出setImmediate和setTimeout。
setTimeout(function() {
setTimeout(function() {
console.log('setTimeout')
}, 0);
setImmediate(function() {
console.log('setImmediate')
});
}, 10);
始终使用setImmediate,除非您真的确定需要使用setTimeout(,0)(但我什至无法想象这是做什么用的)。setImmediate回调几乎总是在之前执行setTimeout(,0),除非是在第一个tick和setImmediate回调中调用时。
setTimeout应该是首选,setImmediate仅在必要时使用。
完全不满意提供的答案。我在这里发布了我认为是更好的答案:https : //stackoverflow.com/a/56724489/5992714
我认为Navya S的答案不正确,这是我的测试代码:
let set = new Set();
function orderTest() {
let seq = [];
let add = () => set.add(seq.join());
setTimeout(function () {
setTimeout(function () {
seq.push('setTimeout');
if (seq.length === 2) add();
}, 0);
setImmediate(function () {
seq.push('setImmediate');
if (seq.length === 2) add();
});
}, 10);
}
// loop 100 times
for (let i = 0; i < 100; i++) {
orderTest();
}
setTimeout(() => {
// will print one or two items, it's random
for (item of set) {
console.log(item);
}
}, 100);
解释在这里