19-事件环-base1

53 阅读2分钟

事件环(Event Loop)

进程

  • cpu 正在进行的一个任务的运行过程的调度单位
  • 浏览器是多进程的应用程序
  • 进程是计算机调度的基本单位
  • 进程包含线程,线程在进程中运行

渲染进程

  • GUI渲染线程 (渲染页面的)
  • JS引擎线程
  • GUI 和 JS引擎线程的运行是互斥的, JS引擎空闲的状态时 GUI渲染任务队列,JS引擎工作的时候GUI冻结
    • 互斥的原因: js脚本的运行中很有可能由DOM操作
    • 验证: js中有死循环,页面显示不出来

GUI渲染线程

  • 1.解析 HTML CSS
  • 2.构建DOM/Render树
  • 3.初始布局与绘制
  • 4.重绘与回流

JS引擎线程

  • 它是由一个主线程 和 多个辅佐线程配合的
  • 一个浏览器只有一个JS引擎
  • 解析js脚本
  • 运行js代码

事件线程 & 事件触发线程

  • 事件线程: 事件环 Event Loop 线程
  • 事件触发线程: 比如: 用户交互事件, setTimeout, ajax等

宏任务 & 微任务

创建线程的目的: 实现异步的执行条件 为什么有 宏/微任务: 主要实现优先级的问题

  • 宏任务: 宿主提供的异步方法和任务
    • script执行 setTimeout UI渲染
  • 微任务: 语言标准(ECMA262)提供的API运行
    • Promise MutationObserver等 示意图如下: image.png
  • 例子1:通过这个例子理解上图
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>事件环</title>
</head>
<body>
   <script>
    document.body.style.backgroundColor = "orange";
    console.log(1);

    setTimeout(() => {
      document.body.style.backgroundColor = "green";
      console.log(2);
    }, 100);

    Promise.resolve(3).then(num => {
      document.body.style.backgroundColor = "purple";
      console.log(num);
    });
    console.log(4);
    /*
        bgColor: orange -> 没渲染
        1
        4
        bgColor: purple -> 渲染
        3
        bgColor: green -> 没渲染
        2
        bgColor: green -> 渲染
    */
    // 1 4 3  2
   </script>
</body>
</html>
    1. script脚本就是宏任务,执行
    1. bgColor: orange -> 没渲染
    1. console.log(1)
    1. setTimeout中的回调函数放到宏任务中
    1. Promise.then回调函数的放到微任务中
    1. console.log(4)
    1. bgColor: purple -> 渲染
    1. console.log(3)
    1. bgColor: green -> 没有渲染
    1. console.log(2)
    1. 微任务为空直接渲染 -> bgColor: green