前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图说 Event-Loop

图说 Event-Loop

作者头像
前端黑板报
发布2021-01-21 10:46:51
6350
发布2021-01-21 10:46:51
举报
文章被收录于专栏:前端黑板报前端黑板报
JavaScript 是单线程的,但是开发者又可以写异步代码!这是怎么做到的呢?

这就需要引入我们今天要讲解的:Event-Loop。

在我们开始之前,先假设要讲解的 Event-loop 是运行在浏览器中的,不是在 Node 或者其它环境里。

我们来介绍一下这篇文章的主角们:

The call stack

Call Stack 是在内存中,用来追踪函数的执行顺序。一个函数会叠加在另一个函数之上,最先添加的函数会最后执行(先进后出)。

The web API

Web API 不是 JS 的一部分,它只是一些可以被 JS 程序使用的方法,例如:setTimeout 、alert 等。

The message queue

message queue 是一个消息的列表,等待与它们相关的函数一起执行。每当被监听的事件触发时,一个新的消息就会被添加到这个列表里。

The event loop

event loop 是一个一直在检测 call stack 是否为空的进程。若 call stack 为空,它就会从 message queue 中取出第一个然后推入 call stack 中执行。

下图是简易浏览器环境:

一个 JS 的故事

让我们看一下,下面的代码以及运行结果:

代码语言:javascript
复制
function foo() {
  console.log("One");
  setTimeout(() => {
    console.log("Two");
  }, 0);
  console.log("Three");
}
foo();

调用 foo 函数,看下结果:

代码语言:javascript
复制
> One
> Three
> Two

现在我们来看看主角们如何执行上面的代码。

首先,浏览器向 call stack 发送 foo() 函数:

console.log('One') 语句被推送到 call stack 的顶部:

同时,event loop 也会检查 call stack 是否为空:

JS 的运行时会执行栈顶的代码然后移除它:

继续向下执行,浏览器向 call stack 推送了 setTimeout() 语句:

event loop 再次检查:

浏览器会设置一个 timer 用来触发 setTimeout 里面的 callback :

接着后面的语句会被推送到 call stack:

event loop 又来了:

event loop 发现 call stack 并没有空所以它什么也不会干,继续向下执行直到 foo() 函数的结尾:

我们来看看 web API 那里为 setTimeout 设置的 timer,现在 timer 结束了。浏览器把对应的 callback 推送到 message queue。

伴随着最后一条语句的执行然后被清除,foo() 函数里面没有可执行的代码了,它也会被 call stack 移出。

现在,event loop 是个幸运儿:

接下来,event loop 会检测 message queue 里是否有消息:

之后会发送消息相关的函数到 call stack:

最后,JS 运行时执行最后的语句,之后从 call stack 里面移出:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端黑板报 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档