我理解中的JS异步

192 阅读2分钟

温故而知新,有一段时间没复习基础知识,重新学习一下,又获得了新知识。

  • 异步 - 起源

    • JS 是单线程语言,只能同时做一件事。
    • 遇到网络请求 ajax、定时任务 setTimeout 等需要等待的操作时,页面不能卡住,因此需要异步。
    • 异步不会阻塞代码执行,它是以回调 callback 函数的形式来实现。
  • 异步 - Event Loop

    • Event Loop,又称 事件循环 或 事件轮询,是异步回调的实现原理。
    • 通过以下步骤,结合图片,了解下 Event Loop 的大致过程:
      1. 同步代码,一行一行放在 Call Stack 执行;
      2. 遇到异步,会先“记录”到 Web APIs,等待时机(定时、网络请求等);
      3. 时机到了,Web APIs 的回调就会移动到 Callback Queue 中;
      4. 若 Call Stack 为空(即同步代码执行完),则 Event Loop 开始工作;
      5. 轮询查找 Callback Queue,若有,则移动到 Call Stack 执行;
      6. 然后,Event Loop 继续轮询查找

event_loop_simple.jpg

  • 异步 - DOM 渲染 -> Event Loop

    • 浏览器中,因为 JS 具备修改 DOM 结构的能力,所以 JS 和 DOM 渲染需要共用一个线程。进而,能触发 DOM 渲染的 DOM 事件也应该是异步,使用基于 Event Loop 的回调来实现。
    • DOM 渲染 -> Event Loop 的步骤如下:
      1. 每次 Call Stack 清空(即每次轮询结束),同步任务执行完;
      2. 都是 DOM 重新渲染的机会,DOM 结构如有变化则需重新渲染
      3. 然后再去触发下一次 Event Loop
  • 异步 - 微任务 -> DOM 渲染 -> Event Loop -> 宏任务

    • 宏任务:
      • 指 setTimeout, setInterval, Ajax, DOM 事件
      • 在 DOM 渲染后触发
      • 由浏览器规定的,存放在 Callback Queue 中
    • 微任务:
      • 指 Promise, async/await
      • 在 DOM 渲染前触发
      • 由 ES6 语法规定的,存放在 Micro Task Queue 中
    • 当最初的 Event Loop 加入了DOM 渲染、宏任务、微任务的概念,可以得出以下更为完整的 Event Loop 示意图。

event_loop_complex.jpg

以上, ^ _ ^