漫谈 Event loop

发布于 6 年前
1 分钟阅读

Philip Roberts 在 JSConf EU 大会上分享了对 Event Loop 的理解,并写了一个可视化工具来展示 Event Loop 的过程。

Event Loop 中最重要的三个概念就是:任务队列,Web Api,调用栈。


调用栈

JS 是单线程的,意味着任意时刻都只有一个任务在执行。同步任务会按顺序进入执行栈。异步任务以队列形式排序等待进入执行栈。所有的异步任务都是在同步任务之后执行。

闭包

在执行 timeout 函数时,我们会发现内部的 log 函数会随后进入调用栈,当 log 函数出栈后 timeout 函数也随之出栈。若 timeout 内部存在一个执行完不能立即出栈的函数,例如一个定时器函数,或者一个被外部引用的内部函数。这个时候 timeout 也出不了栈,就形成了闭包


任务队列

异步 I/O

在理解任务队列之前,我们先来看下什么是异步。

《UNIX网络编程卷1:套接字联网API(第3版)》 第六章第二小节中提到了 5 种 I/O 模型

  1. 阻塞式 I/O
  2. 非阻塞式 I/O
  3. I/O 复用
  4. 信号驱动式 I/O
  5. 异步 I/O

异步 I/O 不导致阻塞,从发起到等待数据到内存复制整个过程都是由内核去完成。待完成之后,内核再通知应用进程。

而从发起到完成整个过程中出现过阻塞行为的 I/O 就被称为同步 I/O。如图所示,除了异步 I/O 之外的 4 种 I/O 模型都被称为同步 I/O。

队列

队列是常见的数据结构之一,遵循先进先出的原则。当内核通知浏览器进程时,回调函数将进入任务队列,再按顺序进入调用栈执行。


WEB API

web api 可以理解为浏览器中非执行线程做的一些事。例如定时器,监听事件。


任务

宏任务代表一个个离散的、独立工作单元。而微任务指的是更小的任务。浏览器先执行一项宏任务,再执行微任务队列中的所有任务。再继续执行一项宏任务,以此循环。


参考资料

What the heck is the event loop anyway? | Philip Roberts | JSConf EU

loupe

《UNIX网络编程卷1:套接字联网API(第3版)》

《JavaScript忍者秘籍(第2版)》

  • 调用栈
    • 闭包
  • 任务队列
    • 异步 I/O
    • 队列
  • WEB API
  • 任务
  • 参考资料