Node.js事件循环机制及与JS区别详解
事件循环机制
事件循环是 Node.js 的重要组成部分,它是 Node.js 实现非阻塞 I/O 的核心。Node.js 中的事件循环采用的是基于 libuv 库的事件循环,它由以下几个部分组成:
- Timers(定时器阶段):处理 setTimeout() 和 setInterval() 的回调函数(这些回调函数由 timer 模块实现);
- I/O callbacks(I/O 操作回调阶段):处理几乎所有的回调函数,除了那些由定时器、setImmediate()、以及关闭的回调函数;
- Idle, prepare:仅在内部使用;
- Poll(轮询阶段):等待有需要被处理的事件出现(如 I/O 事件、定时器),并调用相应的回调函数;
- Check(检查阶段):处理 setImmediate() 设定的回调函数;
- Close callbacks(关闭的回调函数阶段):处理 socket.on('close', ...) 等关闭操作的回调函数。
事件循环的过程是:
- 执行 timers 阶段的回调函数;
- 执行 I/O callbacks 阶段的回调函数;
- 执行轮询(poll)阶段,等待有事件需要处理;
- 执行 check 阶段的回调函数;
- 执行关闭(close callbacks)阶段的回调函数。
这个过程会不停循环执行,直到 Node.js 进程退出。
Node.js 与 JavaScript 的区别
Node.js 的事件循环机制与 JavaScript 的事件循环机制相比,可能需要注意以下几点:
- Node.js 中的事件循环是基于 libuv 库实现的,而 JavaScript 的事件循环是基于浏览器实现的,因此两者在实现上有所不同,但都遵循了先进先出的规则;
- Node.js 中的 setImmediate() 方法可以优先执行于 setTimeout() 方法,因为 setImmediate() 方法是在当前轮询周期末尾执行,而 setTimeout() 方法需等待下一个轮询周期;
- Node.js 的最大特点是单线程,但其通过异步 I/O 和事件循环机制实现了非阻塞式的异步编程模型,这也是它的最大竞争优势;
- 运行在 Node.js 上的 JavaScript 代码与在浏览器上运行的 JavaScript 代码的语法基本相同,但它们所能调用的系统底层 API 不同。
示例说明
示例一:setImmediate() 和 setTimeout() 的区别
console.log('start');
setImmediate(function() {
console.log('setImmediate');
});
setTimeout(function() {
console.log('setTimeout');
}, 0);
console.log('end');
输出结果如下:
start
end
setImmediate
setTimeout
可见,setImmediate() 方法的回调函数会优先执行于 setTimeout() 方法,因为它在当前轮询周期末尾执行。
示例二:process.nextTick() 的使用
console.log('start');
process.nextTick(function() {
console.log('process.nextTick');
});
console.log('end');
输出结果如下:
start
end
process.nextTick
可见,process.nextTick() 方法的回调函数会在当前操作完成后、下一次事件循环前执行,因此它总是比 setImmediate() 和 setTimeout() 执行得更早。注意:如果存在过多的 process.nextTick() 回调函数,将导致当前操作阻塞,所以需要谨慎使用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:node.js事件循环机制及与js区别详解 - Python技术站