详细描述事件循环【原创图解】

事件循环
事件循环是指 JavaScript 引擎在执行代码时,不断地从消息队列中取出事件并处理的一种机制。在浏览器中,事件循环主要用于处理用户交互、网络请求、定时器、以及其他异步操作。
事件循环由以下几个部分组成:

  1. 消息队列:存放所有即将要执行的事件(如鼠标点击事件、定时器事件、网络请求事件等)。
  2. 执行栈:存放正在执行的代码,每当 JavaScript 引擎执行完一个函数时,就会从执行栈中把该函数弹出。
  3. 事件循环:每当执行栈为空时,JavaScript 引擎就会检查消息队列中是否有事件需要处理,如果有就把该事件从消息队列中取出并压入执行栈中执行。
    事件循环的具体流程如下:
  4. 执行全局 JavaScript 代码,将同步任务添加到执行栈中,执行同步任务。
  5. 当遇到异步任务(如定时器、网络请求、鼠标点击事件等)时,将其回调函数添加到消息队列中,等待执行。
  6. 当执行栈中的所有任务都执行完毕时,JavaScript 引擎会去检查消息队列中是否有待处理的事件。
  7. 如果消息队列中有事件,JavaScript 引擎会将其中的一个事件对应的回调函数压入执行栈中执行。
  8. 如果消息队列中有多个事件,JavaScript 引擎会按照它们被添加到消息队列中的顺序,依次将它们对应的回调函数压入执行栈中执行。
    需要注意的是,事件循环只会在执行栈为空的情况下才会去检查消息队列。如果执行栈中一直有任务在执行,事件循环就无法执行。因此,如果某个任务需要执行很长时间,就会阻塞事件循环,导致页面卡顿甚至无响应。
    另外需要注意的是,JavaScript 引擎只有一个线程,因此所有任务都是在同一个线程上执行的,也就是说异步任务只是在规定的时间到了之后才被放到消息队列中等待执行,它并不是在另一个线程上执行的。

在JavaScript中,任务分为宏任务(macro task)和微任务(micro task)两种。
宏任务是由宿主环境提供的任务,通常包括:整体代码Script(script标签中的代码)、setTimeout、setInterval、setImmediate、I/O、UI rendering等。
微任务是指由JavaScript引擎提供的任务,通常包括:Promise、process.nextTick、Object.observe等。
当代码执行时,会产生宏任务和微任务队列。在每个事件循环中,先执行所有的微任务,然后再执行一个宏任务,执行完宏任务后再次执行所有微任务,如此往复循环,直至所有任务执行完毕。
可以将事件循环的过程简单描述为以下几个步骤:

  1. 执行同步代码,产生宏任务和微任务;
  2. 执行所有微任务,按照顺序执行;
  3. 执行一个宏任务,执行完毕后回到步骤2,继续执行微任务;
  4. 当所有任务执行完毕,等待新的宏任务或者退出程序。
    这个过程中,所有的微任务都会在当前宏任务执行完毕前被执行完毕,因此微任务的执行优先级要高于宏任务。

事件循环是 JavaScript 的执行机制,负责协调调度各种任务的执行顺序,包括宏任务和微任务。
宏任务是指由宿主环境(如浏览器)提供的任务,例如setTimeout、setInterval、setImmediate(Node.js环境中)、requestAnimationFrame、I/O等。宏任务会被放入宏任务队列中,等待事件循环从中取出并执行。
微任务是指在当前任务执行完成后立即执行的任务,它的调度优先级要高于宏任务。微任务包括Promise.then、async/await、MutationObserver和queueMicrotask。当微任务队列不为空时,事件循环会先清空微任务队列,再执行宏任务。
在事件循环开始时,先执行当前执行上下文中的同步代码,执行完同步代码后,检查微任务队列是否为空,如果不为空,则依次执行微任务队列中的任务,直到微任务队列为空;接着,从宏任务队列中取出一个任务,执行完毕后,再次执行微任务队列中的任务,如此往复,直到所有队列为空。
需要注意的是,由于每次事件循环只会执行一个宏任务,因此如果当前宏任务的执行时间过长,则会阻塞其他宏任务的执行,导致程序响应变慢,甚至页面卡死。因此,为了避免这种情况,应该尽可能将任务拆分成多个小任务,放入微任务队列中执行。同时,也要避免在微任务中再次触发新的微任务,以免形成无限循环。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值