node事件循环(event loop)

文章详细阐述了Node.js的事件循环机制,包括Timers、I/Ocallbacks、Poll、Check等六个阶段,以及setTimeout、setImmediate、Promise和process.nextTick的执行优先级。在事件循环中,process.nextTick的回调会在当前阶段结束时优先执行,而setImmediate则在Check阶段处理。

Node中事件循环的具体流程图
在这里插入图片描述

事件循环分成了6个不同的阶段,其中每个阶段都维护着一个回调函数的队列,在不同的阶段,事件循环会处理不同类型的事件,其代表的含义分别为:

  • Timers:用来处理setTimeOut()和setInterval()的回调。
  • I/O callbacks:大多数的回调方法在这个阶段执行,除了timers、 close和setImmediate事件的回调。
  • idle, prepare:仅仅在内部使用,我们不管它。
  • Poll:轮询,不断检查有没有新的IO事件,事件循环可能会在这里阻塞。
  • Check:处理setImmediate()事件的回调。
  • close callbacks:处理一些close相关的事件,例如socket.on(‘close’, …)。
console.log('script start');

setTimeout(function(){
  console.log('setTimeout-0');
}, 0)

setTimeout(function(){
  console.log('setTimeout-10');
}, 10)

setImmediate(() => {
  console.log('setImmediate');
})

new Promise((resolve,reject) => {
  console.log('Promise-new');
  resolve()
}).then(() => {
  console.log('promise-then');
})

console.log('script end');
script start
Promise-new 
script end  
promise-then
setImmediate
setTimeout-0
setTimeout-10
console.log('script start');

setTimeout(function(){
  console.log('setTimeout-0');
}, 0)

setTimeout(function(){
  console.log('setTimeout-10');
}, 10)

setImmediate(() => {
  console.log('setImmediate');
})

new Promise((resolve,reject) => {
  console.log('Promise-new');
  resolve()
}).then(() => {
  console.log('promise-then');
})

process.nextTick(function(){
  console.log('process.nextTick');
})

console.log('script end');
script start
Promise-new
script end
process.nextTick
promise-then
setImmediate
setTimeout-0
setTimeout-10

process.nextTick其实并不是事件循环的一部分,但它的回调方法也是由事件循环调用的,该方法定义的回调方法会被加入到名为nextTickQueue的队列中。在事件循环的任何阶段,如果nextTickQueue不为空,都会在当前阶段操作结束后优先执行nextTickQueue中的回调函数,当nextTickQueue中的回调方法被执行完毕后,事件循环才会继续向下执行。

console.log('script start');

process.nextTick(function(){
  console.log('process.nextTick1');

  setTimeout(() => {
    console.log('nextTick-timeOut-10');
  },10)
})
setTimeout(function(){
  console.log('setTimeout-0');
}, 0)

setTimeout(function(){
  console.log('setTimeout-10');
}, 10)

setImmediate(() => {
  console.log('setImmediate');
})

new Promise((resolve,reject) => {
  console.log('Promise-new');
  resolve()
}).then(() => {
  console.log('promise-then');
})

process.nextTick(function(){
  console.log('process.nextTick2');
})

console.log('script end');
script start
Promise-new
script end
process.nextTick1
process.nextTick2
promise-then
setImmediate
setTimeout-0
setTimeout-10
nextTick-timeOut-10
事件循环Event Loop)是编程中用于管理和调度任务执行顺序的重要机制,在不同的编程环境中都有应用,以下是不同场景下事件循环的相关介绍: ### JavaScript 中的事件循环 JavaScript 是一门单线程的编程语言,在执行任务时采用了事件循环机制,这是其核心概念之一,负责管理和调度任务的执行顺序,以确保代码按照预期的方式运行[^1]。 在浏览器环境中,代码会交给 V8 引擎处理,代码里若调用 nodeApi,node 会交给 LIBUV 库处理。LIBUV 通过阻塞 i/o 和多线程实现了异步 io,再通过事件驱动的方式,将结果放到事件队列中,最终交给应用[^4]。 JavaScript 中的任务分为宏任务和微任务。宏任务包括整体代码 script、setTimeout、setInterval、async 函数;微任务包括 Promise.then(非 new Promise)、process.nextTick(node 中)、await 的下一行内容。事件循环的执行顺序是先执行全局同步代码,从上往下执行,接着执行微任务,最后执行宏任务[^5]。 ### Python 中的事件循环 在 Python 中,协程是通过 asyncio 包中的高级 API 来启动的,而 asyncio 模块的核心就是事件循环Event Loop)。它可用于执行异步任务、事件回调、执行网络 IO 操作和运行子进程。官方文档建议开发者尽量使用 asyncio 包提供的高级 API,避免直接使用 Event Loop 对象中的方法[^3]。 ### Node 端的事件循环Node 端,代码调用 nodeApi 后会由 LIBUV 库处理,通过事件驱动将结果放到事件队列中。不过对于 Node事件循环的理解,部分开发者还不够透彻,在具体代码应用方面也存在不足[^2][^4]。 ```python # Python 中使用 asyncio 进行异步编程示例 import asyncio async def hello(): print("Hello") await asyncio.sleep(1) print("World") async def main(): await asyncio.gather(hello(), hello()) asyncio.run(main()) ``` ```javascript // JavaScript事件循环示例 console.log('Global start'); setTimeout(() => { console.log('setTimeout'); }, 0); Promise.resolve().then(() => { console.log('Promise then'); }); console.log('Global end'); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值