事件循环(Event Loop)

事件循环机制

JavaScript引擎是单线程,也就是说每次只能执行一项任务,其他任务都得按照顺序排队等待被执行,只有当前的任务执行完成之后才会执行下一个任务。
任务分为同步任务和异步任务,异步任务永远在同步任务执行完后才执行

调用栈(Call Stack)

是一种后进先出的数据结构。当一个脚本执行的时候,js引擎会解析这段代码,并将其中的同步代码按照执行顺序加入调用栈中,然后从头开始执行。

事件队列 (Task Queue)

js引擎遇到一个异步任务后并不会一直等待其返回结果,而是会将这个任务交给浏览器的其他模块进行处理(以webkit为例,是webcore模块),继续执行调用栈中的其他任务。当一个异步任务返回结果后,js引擎会将这个任务加入与当前调用栈不同的另一个队列,我们称之为事件队列。
事件循环的图示
当一个脚本执行的时候,js引擎会解析这段代码,并将其中的同步代码按照执行顺序加入调用栈中,然后从头开始执行。

js引擎遇到一个异步事件后并不会一直等待其返回结果,而是会将这个事件挂起(其他模块进行处理),继续执行执行栈中的其他任务。当一个异步事件返回结果后,js会将这个事件加入到事件队列。

被放入事件队列不会立刻执行其回调,而是等待当前执行栈中的所有任务都执行完毕, 主线程处于闲置状态时,主线程会去查找事件队列是否有任务。如果有,那么主线程会从中取出排在第一位的事件,并把这个事件对应的回调放入执行栈中,然后执行其中的同步代码…,如此反复,这样就形成了一个无限的循环。这个过程被称为“事件循环(Event Loop)”。

异步任务

不同的异步任务被分为两类:微任务(micro task)和宏任务(macro task)。
macro-task: 整体代码script、setTimeout、setInterval…
micro-task:Promises、Object.observe…

在一个事件循环中,异步事件返回结果后会被放到一个任务队列中。
根据这个异步事件的类型,实际上会被放到宏任务队列或者微任务队列。
当前调用栈执行完毕时会优先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。
异步任务图示

事件循环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'); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值