浅谈JavaScript的事件循环机制(Event Loop)- 浏览器篇|8月更文挑战

前言

咱们先来看个实际中的场景:javascript

在浏览器上打印出1~100万。java

对于这个需求,咱们第一个反应的代码是这样的:浏览器

for (let i = 0; i < 100 * 10000; i++) {
    const div = document.createElement("div");
    div.innerText = i;
    document.body.append(div);
  }
复制代码

看着好像没问题,固然这里有的同窗会说,你这里操做了100万次dom,性能损耗很严重。这是一个问题,可是这个不是本文讨论的重点。markdown

咱们实际运行一下这段代码,发现一开始的时间(很短)会没法正常作交互,好比鼠标悬浮,选中文字等操做。那么为何会形成这个现象呢?不急,咱们一步步分析。app

浏览器的渲染机制

以Chrome为例,一个标签页独占一个渲染进程,而JavaScript解释线程是属于这个渲染进程内的。dom

咱们先聊下前置知识,JavaScript执行和屏幕渲染是互斥的,缘由是屏幕渲染须要根据DOM结构,而JavaScript是有能力修改DOM的,因此会在JavaScript执行完毕后,执行渲染动做。通常来讲,屏幕的渲染是60HZ,差很少16ms须要切换一张图片,人眼才不会意识到卡顿。异步

那么咱们再回来看刚刚的代码async

for (let i = 0; i < 100 * 10000; i++) {
  }
复制代码

结论很明显了,这句代码的执行明显超过了16ms!!!oop

事件循环机制

事件循环机制(Event Loop)就是为了解决这个问题而提出的。性能

简单来讲,咱们把大任务切成了多个小任务,让这些任务的执行和渲染流程交错进行。

计算100万个(1s) => 屏幕渲染

计算10万个(0.1s) => 屏幕渲染 => 计算10万个(0.1s) => 屏幕渲染 => 计算10万个(0.1s) => ...

这里就不贴出具体的代码实现了,感兴趣的同窗能够本身动手写一下。

再探事件循环机制

事件循环机制(Event Loop)出现后,JavaScript的执行任务分为了两类:同步任务和异步任务。而异步任务,又分红了两类:

  • 宏任务(Macrotask)总体代码定时器I/O
  • 微任务(Microtask)PromiseMutationObserverobserver

这里咱们须要注意一点,Promise自己是同步代码,可是它的回调then catch是异步

new Promise((res, rej) => {
    res('ok') // 同步任务
  }).then((result) => {
    console.log(result) // 异步任务中的微任务
  })
复制代码

其实咱们会好奇,为何是分红这两类?为何不是三类或者一类?其实这是一种权衡的策略。宏任务的定义为耗时长的任务,微任务为耗时短的任务。在实际执行中,须要执行的任务分红多,因此就会有优先级的问题,其实宏任务和微任务的制定就是一种折中,为了权衡执行时间和运行效率。

优先级问题

咱们刚刚提到了优先级的问题,那咱们就来展开聊聊。通常状况下,微任务的执行优于宏任务。为何是通常状况下呢?咱们来看下这段代码:

for(let i = 0; i < 10; i++) {
    setTimeout(() => {
      console.log('宏任务开始')
      for (let j = 0; j < 10; j++) {
        microtask();
      }
    })
  }

  function microtask() {
    return new Promise(async (res) => {
      console.log('微任务开始')
      await microtask();
      res();
    })
  }
复制代码

注册10个宏任务 => 运行第1个宏任务 => 注册10个微任务 => 微任务执行过程当中又注册了微任务 => 微任务执行过程当中又注册了微任务 => ...

这是一个微任务的死循环,若是按微任务的执行优于宏任务的论据,宏任务是不可能触发第二个的,由于微任务队列一直在被push。

可是实际状况下,咱们是能够看到第二个宏任务开始的。这是为何呢?实际上是Chrome V8作的一个小策略,在微任务过多的时候,会执行下一个宏任务。

小结

咱们经过了开头的一个小例子,引入了事件循环机制(Event Loop),而执行任务分为了两类:同步任务和异步任务。而异步任务,又分红了两类:宏任务和微任务。通常状况下,微任务的执行优于宏任务。当在极端场景下,好比微任务实在是太多了,Chrome V8会先执行宏任务。

最后打波小广告,美团校招社招内推,不限部门,不限岗位,不限投递数量,海量hc,快来快来~

相关文章
相关标签/搜索