bibi7 / node-note

不做commit,issue用来放一些学习node的时候的笔记,纯粹记给自己看的东西,不能保证正确性。
MIT License
0 stars 0 forks source link

一些与I/O无关的异步API #8

Open bibi7 opened 6 years ago

bibi7 commented 6 years ago

这部分见到几个眼熟的老朋友了。

bibi7 commented 6 years ago

两个老朋友: setTimeout() setInterval()

两个新朋友: setImmediate() process.nextTick()

bibi7 commented 6 years ago

setTimeoutsetInterval() 与浏览器中一致,但是相比浏览器根据定时完毕后推入宏队列不太一样。

使用这两者创建的定时器会被插入定时器观察者内部的一个红黑树中,每次Tick执行时,会从该红黑树中迭代取出对象来检查是否超过定时时间,如果超过就形成一个事件,回调函数立即执行。 有个问题点是,如果某次循环占用的时间较多,会稍稍存在超时可能,也就是不一定是很精准的定时。 p61 图3-14

bibi7 commented 6 years ago

process.nextTick() 在未了解process.nextTick()之前,很多人为了立即执行一个异步任务都会调用setTimeout()

setTimeout(function () {
    //todo
}, 0)

(惊了惊了,我也是这样想的。。。)

bibi7 commented 6 years ago

由于事件循环的原因,定时器的精确度往往会有偏差,另外定时器需动用红黑树,以及一些迭代操作,setTimeout(fn, 0)的方式会比较浪费性能。

process.nextTick()会将回调函数放入队列中,下一轮Tick取出执行,时间复杂度比定时器低,所以会高效一点

bibi7 commented 6 years ago

setImmediate()process.nextTick()异曲同工之妙,后者的优先级会优于前者,其实说nextTick是下一轮tick中取出执行也不是完全对正确的来说process.nextTick()是在当前结束之后,立即执行,插在下一轮tick之前。 而setImmediate()是真正的处于第二轮tick。

bibi7 commented 6 years ago

放几张图感受一下: image image image

bibi7 commented 6 years ago

还有另一种说法:

nextTick是加到队列头,setImmediate是加到队列尾

也可以这样理解