node中的异步API

640?wx_fmt=png我们都知道Node自身的执行模型是事件循环,所以事件循环是一个比较重要的知识点,理解了事件循环就能够清楚的知道代码的执行先后顺序。事件循环都有对应的观察者,然后事件循环从观察者中取出事件并执行。



01

setTimeout、setInterval


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

640?wx_fmt=png


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


640?wx_fmt=png


02

process.nextTick


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


03

setImmediate


setImmediate() 方法与 process.nextTick() 方法十分类似,都是将回调函数延迟执行。


process.nextTick() 中的回调函数执行的优先级要高于 setImmediate() 。这里的原因在于事件循环对观察者的检查是有先后顺序的, process.nextTick() 属于idle观察者, setImmediate()属于check观察者。


640?wx_fmt=png


推荐图书



技术决定你能走多快,数据结构和算法决定你能走多远。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值