一、setImmediate和setTimeout的区别
setTimeout是浏览器常用的一个定时器函数,但它的延时可能不完全准确,会受到系统性能和浏览器工作的影响。而setImmediate则是Node.js在v0.10版本及以后推出的一个函数,用于产生一个异步操作,它的执行时机是在本轮事件轮询的结束阶段,即setTimeout/setInterval执行的定时器器触发时机之前。
举个例子,假如一旦你有一个需求,需要断断续续的往服务端传送数据,其中每一次传送的间隔可以是1s,在这种情况下,我们可以用setTimeout来实现循环发送数据,代码如下:
setData() function setData(){ // 模拟的数据上传的操作 console.log(`Upload data at ${new Date().toLocaleString()}`) // 需要隔1s传一次数据 setTimeout(setData, 1000) }
上面的代码可以实现每隔1秒上传一次数据的需求,但是它的优先级是在定时器触发完成之后。如果在触发定时器的同时,页面上又触发了其他事件,控制权就会被划分到下一个事件轮询,这就可能导致定时器在1000ms后才能触发。而setImmediate是在每轮事件轮询结束阶段执行,能够保证程序的更高优先级,假如我们把上面的代码改为使用setImmediate:
setImmediate(setData) function setData(){ // 模拟的数据上传的操作 console.log(`Upload data at ${new Date().toLocaleString()}`) // 需要隔1s传一次数据 setImmediate(setData) }
这样就可以在更高优先级的情况下实现每隔一秒上传数据了。
二、setImmediate和setTimeInterval的区别
如果将setImmediate和setTimeInterval进行对比,实际上明显的不同之处就是其在事件队列中的执行时机。setImmediate的优先级更高,会在当前事件的尾部挂载,而setTimeInterval则会在事件队列中等到当前所有任务都完成之后再继续执行下一个处理器。下面的代码展示了一个使用两个定时器的示例:
setImmediate(() => { console.log(`setImmediate at ${new Date().toLocaleString()}`) }) setInterval(() => { console.log(`setInterval at ${new Date().toLocaleString()}`) }, 0)
执行上面的代码,会输出如下结果:
setImmediate at 23:47:18 setInterval at 23:47:18 setInterval at 23:47:18 setInterval at 23:47:18 ...
上面的结果展示了setImmediate在setTimeout执行之前开始了,而setInterval在第一个事件处理完成之后才开始执行。
三、setImmediate MDN
setImmediate()方法创建一个立即执行的计时器,它为事件循环系统提供了一个执行时间回调的更良好的方式,即避免了在下一次事件轮询之前执行延时回调时带来的副作用。通常,使用setImmediate()比使用setTimeout()带有更高的性能,因为它不需要设置任何定时器。以下是具有一定参考价值的MDN代码示例:
console.log('start') setImmediate(() => { console.log('immediate') }) setTimeout(() => { console.log('timeout') }, 0) console.log('end')
在上面的代码中,setImmediate回调的执行优先级更高,所以’Immediate’的log输出优先显示。
四、immediate副词
最后一个和setImmediate相关的话题是immediate副词。这个副词会在事件循环结束时(当前运行在 Node.js v0.10 或更高版本的情况下)立即被调用。当已经运行了回调处理时,immediate副词就不会被再调用。下面是一个例子:
setImmediate(() => { console.log('setImmediate') }) process.immediate(() => { console.log('process.immediate()') })
上面的代码将分别在事件循环结束时和立即调用immediate副词的process.nextTick()方法中来显示它们的输出。如果你尝试在同一事件循环中多次调用它们,你会发现immediate副词只会被调用一次。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/304289.html