什么是javascript的事件循环

JavaScript 的 事件循环(Event Loop) 是其执行机制的核心,用来处理异步操作,使得 JavaScript 能够实现非阻塞式的单线程异步编程。为了理解事件循环,首先要了解 JavaScript 是单线程的语言,这意味着它一次只能执行一个任务。但在实际应用中,比如 I/O 操作(网络请求、定时器、用户事件等),JavaScript 使用事件循环机制来管理异步任务,使其在需要的时候能继续执行而不阻塞主线程。

1. JavaScript 执行模型概览

JavaScript 的执行环境中包括以下几个关键概念:

  • 调用栈(Call Stack):调用栈是 JavaScript 用来管理函数执行的地方。当一个函数被调用时,它会被压入调用栈,执行完成后弹出。

  • 任务队列(Task Queue):也叫 消息队列(Message Queue),存放异步任务的回调函数,如 setTimeoutPromise、事件处理函数等。

  • 事件循环(Event Loop):事件循环是负责检查调用栈是否为空,并决定何时将任务队列中的任务推入调用栈执行的机制。

2. 事件循环的运行机制

事件循环的核心工作流程如下:

  1. 同步任务:所有同步任务都会直接在 调用栈(Call Stack) 上依次执行。

  2. 异步任务:当遇到异步任务(如 setTimeoutPromise、I/O 操作)时,这些任务会被放到相应的 任务队列 中,而不会立即执行。

  3. 事件循环(Event Loop):事件循环会不断检查调用栈是否为空。当调用栈为空时,它会查看 任务队列 是否有可执行的任务。如果有,它会将任务队列中的第一个任务放入调用栈中执行。

  4. 继续执行:当某个异步任务的回调函数被执行完,事件循环会再次检查任务队列,重复上述过程。

3. 宏任务和微任务

JavaScript 中的异步任务大致可以分为 宏任务(Macro-task)微任务(Micro-task),这两者的执行顺序是事件循环中至关重要的部分。

  • 宏任务(Macro-task)包括:setTimeoutsetIntervalI/O 操作、script(整体代码)、事件监听器等。

  • 微任务(Micro-task)包括:Promise.then()process.nextTick(Node.js)、MutationObserver

执行顺序:
  1. 事件循环每次循环称为一个 tick,每次 tick 开始时,会先执行 调用栈中的所有同步任务

  2. 当调用栈为空后,会执行 微任务队列(Micro-task Queue) 中的所有任务,直到微任务队列清空。

  3. 在微任务执行完毕之后,事件循环才会去执行下一个 宏任务队列 中的任务。

  4. 重复以上步骤。

示例:
console.log('Start'); // 同步任务

setTimeout(() => {
  console.log('Macro-task: setTimeout'); // 宏任务
}, 0);

Promise.resolve().then(() => {
  console.log('Micro-task: Promise'); // 微任务
});

console.log('End'); // 同步任务

执行顺序

  1. console.log('Start')console.log('End') 是同步任务,直接进入调用栈依次执行。
  2. setTimeout 是宏任务,它的回调函数会被放入宏任务队列中,稍后执行。
  3. Promise.then 是微任务,微任务会在同步任务结束后立即执行。
  4. 最后,setTimeout 的回调才会执行。

输出结果

Start
End
Micro-task: Promise
Macro-task: setTimeout

4. 典型的异步操作

  • setTimeoutsetInterval:它们是常见的定时器函数,回调函数会被放入宏任务队列中,等待事件循环调度。

  • PromisePromise 是微任务,它的 thencatch 回调会被放入微任务队列中,优先于宏任务执行。

  • requestAnimationFrame:这个函数专门用于高效的动画渲染,在浏览器的帧刷新之前执行其回调。

  • I/O 操作:如网络请求的回调会在 I/O 事件完成后放入宏任务队列中。

5. 事件循环在浏览器和 Node.js 中的区别

  • 浏览器 中,事件循环的机制更侧重于处理用户事件和 UI 渲染。每次事件循环中的宏任务执行完之后,浏览器会重新渲染页面,然后再执行下一个任务。

  • Node.js 的事件循环更复杂一些,尤其在处理 I/O 和定时器方面有更详细的阶段划分。Node.js 的事件循环大致分为几个阶段:timers 阶段(执行定时器回调)、I/O callbacks 阶段、idle, prepare 阶段、poll 阶段(处理 I/O 事件)、check 阶段(执行 setImmediate)、close 阶段(关闭回调)。

6. 事件循环的应用场景

  • 异步编程:事件循环机制使得 JavaScript 能够在单线程中高效处理 I/O 操作、定时器、DOM 操作等任务,不会阻塞主线程。

  • 优化性能:在用户界面更新时,长时间的同步任务可能导致页面卡顿,理解事件循环可以帮助你将耗时的任务异步处理,从而保持页面的流畅度。

  • 微任务与宏任务优化:通过合理使用微任务和宏任务,你可以控制任务的优先级,从而优化程序的执行顺序。

总结:

  • 事件循环 是 JavaScript 中实现异步编程的核心机制,它不断检查调用栈和任务队列,确保异步任务在适当的时间点执行。
  • 异步任务分为 宏任务微任务,微任务的优先级高于宏任务。
  • 事件循环的机制使得 JavaScript 能够处理大量 I/O、定时器、DOM 操作等任务而不阻塞主线程执行。

理解事件循环对于编写高效、流畅的 JavaScript 代码至关重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端李易安

打赏1元鼓励作者

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值