JavaScript事件循环

CSDN话题挑战赛第2期
参赛话题:学习笔记

学习之路,长路漫漫,写学习笔记的过程就是把知识讲给自己听的过程。这个过程中,我们去记录思考的过程,便于日后复习,梳理自己的思路。学习之乐,独乐乐,不如众乐乐,把知识讲给更多的人听,何乐而不为呢?

事件循环(EventLoop)

事件循环 是一个在 JavaScript 引擎等待任务,执行任务和进入休眠状态等待更多任务这几个状态之间转换的无限循环。

JavaScript代码在执行时,会被push进一个调用栈中,EventLoop通过两个队列来实现事件队列放进来的异步任务。以setTimeout为代表的任务称为宏任务,放到宏任务队列中。以promise为代表的任务称为微任务,放到微任务队列中。

调用堆栈:负责跟踪所有要执行的代码
事件队列:负责将新的function发送到队列中进行处理,每当调用事件队列中的异步函数时都会将其发送到浏览器API,根据从调用栈收到的命令,API开始进行单线程操作。

宏任务:

  • setTimeout
  • setInterval
  • I/O
  • UIrendering
  • event listener

微任务:

  • promise
  • Object.observe
  • mutationObserver

JavaScript引擎从宏任务队列中取出第一个任务,执行完毕后将微任务中的所有任务取出按照顺序分别全部执行,如果在这一步中产生新的微任务,也需要执行。

从宏任务队列中取出下一个,执行完毕后,再次将microtaskqueue中的全部取出,循环往复,直到两个queue中的任务都取完。

执行流程

引擎的一般算法:
当有任务时:

  • 从最先进入的任务开始执行。
  • 休眠直到出现任务,然后转到第 1 步。
    当我们浏览一个网页时就是上述这种形式。JavaScript 引擎大多数时候不执行任何操作,它仅在脚本/处理程序/事件激活时执行。
    一个任务到来时,引擎可能正处于繁忙状态,那么这个任务就会被排入队列。多个任务组成了一个队列,即所谓的“宏任务队列”。宏任务的队列可以理解为一个事件循环。
    在这里插入图片描述

执行任务的顺序

  1. 从 宏任务 队列(例如 “script”)中出队(dequeue)并执行最早的任务。
  2. 执行所有 微任务:
    当微任务队列非空时:
    出队(dequeue)并执行最早的微任务。
  3. 如果有渲染任务,执行渲染。
  4. 如果宏任务队列为空,则休眠直到出现宏任务。
  5. 转到步骤 1。

EventLoop对渲染的影响

requestAnimationFrame()可以在下一次渲染执行之前执行回调函数。在每一次Eventloop的末尾判断当前是否处于渲染时机。渲染时机指以下情况,有屏幕的硬件限制,浏览器的渲染间隔时间就没必要小于16.6ms。


版权声明:本文为qq_40850839原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。