node 异步I/O
为什么要使用异步I/O
- 采用异步请求,在下载资源期间,JavaScript和UI的执行都不会处于等待状态,可以继续响应用户的交互行为。
- 同步与异步时间消耗对比,前者时间为M+N,后者为max(M+N)
简介:node优势所在,内部使用的线程池原理实现
ps: javascript代码运行在单线程上,但是node自身是多线程的,内部I/O是多线程的
- 现实中的异步:
- linux下
node在linux下的异步I/O使用的是epoll,该方案是linux下效率最高的I/O事件通知机制。
其原理为:在事件轮询中如果未检测到未处理事件则进入休眠,知道事件将其唤醒 - wibdows下
node在windows下的异步I/O通过IOCP,在某种程度上IOCP提供了理想的异步
I/O:不需要事件的轮询,在事件完成后通过回调将数据返回即可 - 两者的区别
在*unix下线程池由libuv创建,在windows下由ICOP提供
- linux下
- 理想中的异步:
- 事件循环机制:
- 完整的异步I/O流程图:
- 完整的web服务器流程图:
非I/O的异步API
- setTimeout,setInterval
- 实现原理和异步I/O相似,不需要线程池
- 两者创建的定时器会被插入到定时器观察者内部的一个红黑树中
- 每次Tick执行时会迭代取出检测是否超过指定时间,超过即创建一个事件立即执行
- 缺点:有时会出现稍微的偏差, 由于要操作红黑树,较为浪费性能
- process.nextTick
调用process.nextTick方法即将当前事件放入队列中,待下一次Tick时执行
- setImmediate
原理和process.nextTick一样,都是将当前事件放入队列中,待下一次Tick时执行
- process.nextTick和setImmediate的差别
- nextTick属于idel观察者,优先级高于setImmediate(check观察者)
- nextTick:一次循环中执行完当前队列中的所有nextTick事件,setImmediate一次循环执行队列中的一个事件