事件循环 EventLoop

140 阅读2分钟

本文已参与 「新人创作礼」活动, 一起开启掘金创作之路。

R-C.jpg

事件循环 Event Loop

  1. 介绍: javaScript 是一款单线程的语言, 他的异步和多线程的实现是由事件循环机制 Event Loop 来实现的
  2. 大体由三个部分组成: a: 调用栈(call stack); b: 消息队列(Message Queue) 就是用来存放宏任务的队列; c: 微任务队列(Microtask Queue)
  3. 过程: Event Loop 开始时, 会从全局栈开始一行一行执行, 遇到函数调用会把它压入栈中, 被压入的函数 fn() 叫做 帧(Frame)
  4. 宏队列 macrotask(tasks): setTimeout setInterval setImmediate (Node独有) requestAnimationFrame (浏览器独有) I/O UI rendering (浏览器独有)
  5. 微队列 microtask(jobs): process.nextTick(Node独有) Promise Object.observe MutationObserver
  6. 讲一下 JavaScript 代码的具体流程:
    a. 首先执行 Script 的同步代码, 这些代码有一些是同步语句, 有一些是异步语句(比如 setTimeout promise等)
    b. 全局 Script 代码执行完毕以后, 调用栈会被清空
    c. 从微任务队列 (Microtask Queue) 中取出位于队首的回调任务, 放入调用栈 Stack 中执行, 执行完毕以后 (Microtask Queue) 的长度减一
    d. 继续取出队首的任务依次执行, 直到 (Microtask Queue) 中的所有任务都执行完毕。如果在执行 (Microtask Queue) 的过程中, 又产生了新的 Microtask 那么加入到队列的末尾, 也会在这个周期里执行。
    e. (Microtask Queue) 队列所有任务执行完毕以后, 队列为空, 调用栈 Stack 也为空
    f. 取出消息队列 (Message Queue) 中位于队首的任务, 放入执行栈 Stack 中执行
    g. 执行完毕以后, 调用栈 Stack 为空
    z. 重复 c-g
  7. 总结一下: 1 宏队列macrotask一次只从队列中取一个任务执行,执行完后就去执行微任务队列中的任务; 2 微任务队列中所有的任务都会被依次取出来执行,直到 microtask queue为空;