《译》惊艳!动态图演示 - 事件循环 Event Loop

前言

对于事件循环,这是每一个 JavaScript 开发人员必然会遇到或者须要理解的内容之一。javascript

可是对于初级开发者来讲,理解起来可能有些混乱。java

由于我是一个视觉学习者,因此我经过低分辨率 gif 图的可视化方式来帮助你理解它。git

事件循环

可是首先,事件循环是什么,为何要关心呢?github

JavaScript 是 单线程的:一次只能运行一个任务。浏览器

一般,这没什么大不了的,可是如今想象你正在运行一个耗时 30 秒的任务。数据结构

在此任务中,咱们等待 30 秒才能进行其余任何操做(默认状况下,JavaScript 在浏览器的主线程上运行,所以整个用户界面都停滞了)😬 。异步

都到 2020 年了,没有人想停留在一个速度慢,交互反应迟钝的网站。函数

幸运的是,浏览器为咱们提供了JavaScript 引擎自己不提供的一些功能:Web API。oop

这包括 DOM API,setTimeout HTTP 请求等,这能够帮助咱们建立一些异步的,非阻塞的行为。post

当咱们调用一个函数时,它会被添加到称为 调用栈 的数据结构中。

调用栈是 JS 引擎的一部分,这不是特定于浏览器的。

它是一个调用栈,这意味着它是 先进先出 的(例如一堆煎饼)。

当一个函数返回一个值时,它会从调用栈中弹出 👋。

respond 函数返回一个 setTimeout 函数。

setTimeout 由 Web API 提供给咱们:它让咱们拖延的任务,而不会阻塞主线程。

咱们传递给该 setTimeout 函数的回调函数,箭头函数 () => { return "Hey" } 已添加到 Web API。

同时,该 setTimeout 函数和 response 函数从调用栈中弹出,它们都返回了它们的值!

在 Web API中,计时器的运行时间与咱们传递给它的第二个参数 1000ms 同样长。回调不会当即添加到调用栈中,而是会传递给称为队列的东西。

这多是一个使人困惑的部分:这并不意味着在 1000 毫秒后将回调函数添加到调用栈中(从而返回一个值)!它只是在 1000 毫秒后添加到 队列中。但这是一个队列,该功能必须等待轮到它!

接下为是咱们一直在等待的重点内容……

让事件循环执行其惟一的任务了:将队列与调用栈链接起来!若是调用栈为 ,那么若是全部先前调用的函数都返回了它们的值并已从堆栈中弹出,则队列中的 第一项 将添加到调用栈中,在这种状况下,没有其余函数被调用,这意味着当回调函数成为队列中的第一项时,调用栈为空。

回调被添加到调用栈中,被调用,并返回一个值,并从调用栈中弹出。


例子

阅读一篇文章颇有趣,可是经过反复地实际操做,你会对此理解得更深。

若是运行如下 js,请想一下控制台会输出什么内容:

const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"), 500);
const baz = () => console.log("Third");

bar();
foo();
baz();
复制代码

想出答案了吗?

让咱们快速看一下在浏览器中运行此代码时发生的过程:

  1. 咱们调用 barbar 返回一个 setTimeout 函数。

  2. 咱们传递给的回调 setTimeout 被添加到 Web API,该 setTimeout 函数中,并 bar 从调用堆栈中弹出。

  3. 计时器运行,同时 foo 调用并记录 Firstfoo 返回(未定义),baz 被调用,并将回调添加到队列中。

  4. baz 输出 Third,事件循环看到 baz 返回后调用栈为空,而后将回调添加到调用栈。

  5. 回调再打印出 Second


但愿这会使你对事件循环的理解更加清析!最重要的是 了解某些错误 / 行为可能从何而来

当遇到不明白的地方时,也能 高效地Google 上搜索正确的关键字 ,并能搜索到正确的答案 💪🏼 。

最后

外国友人技术博客的语言表达的方式和风格、与国人的仍是有很大差异的啊。

姐妹篇:惊艳!可视化的 js:动态图演示 Promises & Async/Await 的过程!

翻译了两篇文章,仍是蛮有趣的 😇,瞬间感受本身的英文水平高达 8 级了啦 (白日梦 🤩)。

推荐阅读: 经过10 个实例小练习,快速入门熟练 Vue3 核心新特性

支持一下下👇

相关文章
相关标签/搜索