Node.js中非I/O的异步API

Node中存在一些与I/O无关的异步API,分别是setTimeout()、setInterval()、setImmediate()和process.nextTick().

setTimeout()和setInterval()分别用于单次和多次定时执行任务,不需要I/O线程池参与,调用setTimeout()或setInterval()创建的定时器会被插入到定时器观察者内部的一个红黑树中。每次Tick执行时,会从该红黑树中迭代取出定时器对象,检查是否超过定时时间,如果超过,就形成一个事件,它的回调函数将立即执行。

定时器的问题在于它并非精确的,尽管事件循环十分快,但是如果某一次循环占用的时间较多,那么下次循环时,它也许超时很久了,譬如通过setTimeout()设定一个任务在10ms后执行,但是在9ms后,有一个任务占用了5ms的CPU时间,再次轮到定时器任务时,时间就已经过期4ms。

在未了解process.nextTick()之前,很多人也许为了立即异步执行一个任务,会调用setTime(fn,0)来达到所需的效果。

由于事件循环自身的特点,定时器的精度不够,而事实上,采用定时器需要动用红黑树,创建定时器对象和迭代等操作,而setTimeout()的方式较为浪费性能,process.nextTick()方法的操作较为轻量,每次调用process.nextTick()方法,只会将回调函数放入队列中,在下一轮tick时取出执行。

setImmediate()方法和process.nextTick()类似,都是将回调函数延迟执行,但是process.nextTick中的回调函数的优先级要高于setImmediate,这是因为事件循环对观察者的检查是有先后顺序的,process.nextTick()属于idle观察者,setImmediate属于check观察者,在每一轮循环检查中,idle观察者优选与I/O观察者,I/O观察者优先于check观察者。

猜你喜欢

转载自blog.csdn.net/qq_37263757/article/details/84240029