node.js中的setImmediate()与process.nextTick()

来源:互联网 发布:淘宝等级权限 编辑:程序博客网 时间:2024/05/20 19:16

        Node.js是单线程的,基于事件循环,非阻塞 IO的。事件循环中使用一个事件队列,在每个时间点上,系统只会处理一个事件,即使电脑有多个CPU核心,也无法同时并行的处理多个事件。因此,node.js适合处理I/O型的应用,不适合那种CPU运算密集型的应用。在I/O型的应用中,给每一个输入输出定义一个回调函数,node.js会自动将其加入到事件轮询的处理队列里,当I/O操作完成后,这个回调函数会被触发,系统会继续处理其他的请求。

node.js中定时器问题

        在于它并非精确,例如:setTimeout()设定一个任务在10ms后执行,但是在8ms后,有一个任务占用了5ms,定时器将被耽误3ms。

即时计时器立即执行工作

        即时计时器用来在I/O事件的回调函数开始执行后,但任何超时时间或时间间隔时间被执行之前,立即执行工作。允许把工作调度在事件队列中的当前事件完成之后执行。应该使用计时定时器为其他回调产生长期运行的执行段,以防止I/O事件饥饿。调用setImmediate()时,回调函数被放置在事件队列中,并在遍历队列循环的每次迭代中,在I/O事件有机会被调用后弹出一次。

使用nextTick来调度工作

        nextTick()在I/O事件被触发之前执行,这可能导致I/O事件的饥饿。所以Node.js通过默认值为1000的process.maxTickDepth来限制事件队列的每次循环可执行的nextick()事件的数目。

nextTick()和setImmediate()区别

        nextTick()的回调函数执行的优先级要高于setImmediate()。process.nextTick()属于idle观察者,setImmediate()属于check观察者.在每一轮循环检查中,idle观察者先于I/O观察者,I/O观察者先于check观察者。

        在具体实现上,process.nextTick()的回调函数保存在一个数组中,setImmediate()的结果则是保存在链表中。在行为上process.nextTick()在每轮循环中会将数组中的回调函数全部执行完,而setImmediate()在每轮循环中执行链表中的一个回调函数。

        process.nextTick 是将异步回调放到当前帧的末尾、io回调之前,如果nextTick过多,会导致io回调不断延后,最后callback堆积太多。setImmediate 是将异步回调放到下一帧,不影响io回调,不会造成callback 堆积。

0 0