16

【动画演示】:事件循环 形象深动(JavaScript)

 4 years ago
source link: https://juejin.im/post/5e0a8d57f265da33a55fb33c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
2019年12月31日 阅读 2190

【动画演示】:事件循环 形象深动(JavaScript)

作者:Lydia Hallie

译者:前端小智

来源: dev

点赞再看,养成习惯

本文 GitHub github.com/qq449245884… 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。


事件循环是什么,为什么要理解它?

JS 是单线程的:一次只能运行一个任务。通常这没什么大不了的,但现在想象一下我们正在运行一个需要30秒的任务。在这个任务中,我们要等待30秒,然后才能执行接下来要做的事情(JS 默认运行在浏览器的主线程上,所以整个UI都卡住了)。

幸运的是,浏览器提供了 JS 引擎本身没有提供的一些特性:Web API。这包括DOM APIsetTimeoutHTTP请求等等。这些 API 可以帮助我们创建一些异步的、非阻塞的行为。

当我们调用一个函数时,它被添加到调用堆栈中。调用堆栈是JS引擎的一部分,这不是浏览器特有的。堆栈里面的顺序是先进后出,当函数返回一个值时,它会从堆栈中弹出。

16f593a10a0c419a?imageslim

response函数返回一个setTimeout函数。setTimeout是由Web API提供的:它允许我们在不阻塞主线程的情况下延迟任务。我们传递给setTimeout函数的回调函数()=> {return 'Hey'}被添加到Web API中。与此同时,setTimeout函数和response函数从堆栈中弹出,它们都返回了它们的值。

16f593a6a4db9f20?imageslim

Web API中,计时器的运行时间与我们传递给它的第二个参数1000ms一样长。 回调不会立即添加到调用堆栈中,而是会传递到队列中。

16f593a9070ae489?imageslim

这可能是一个令人困惑的部分:它并不意味着在1000ms之后将回调函数添加到调用堆栈中,它只是在1000ms后添加到队列中。在队列,函数必须等待轮到它,才会执行。

现在,我们一直在等待事件循环完成其惟一的任务:将队列与调用堆栈连接起来。如果调用堆栈为空,那么如果之前调用的所有函数都返回了它们的值并已从堆栈中弹出,则队列中的第一项将添加到调用堆栈中。在本例中,没有调用其他函数,这意味着在回调函数成为队列中的第一项时,调用堆栈为空。

16f593ab3dabc83e?imageslim

回调函数被添加到调用堆栈中,被调用,并返回一个值,然后从堆栈中弹出。

16f593ae93abe50b?imageslim

通过动画演示看起来是很有趣的,但还是需要重复多看几遍,才能更好理解它们之间的关系。现在来考验一下,如下代码所示,请说出执行的结果:

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

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

明白了吗?让我们快速查看一下在浏览器中运行这段代码时发生了什么

16f593b2275fec67?imageslim

1.调用函数barbar返回setTimeout函数。

2.我们传递给setTimeout的回调被添加到Web APIsetTimeout函数和bar从调用栈中弹出。

3.计时器运行,同时函数foo被调用并打印 Firstfoo返回,接着调用函数baz,并将回调添加到队列中。

4.函数baz打印Third,事件循环看到baz返回后,调用栈为空,然后将处理队列中的回调添加到调用栈中。

  1. 回调函数打印 Second

希望本文对你在事件循环上的理解有一定的帮助,咱们下篇见。


原文:dev.to/lydiahallie…

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug


交流

干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。

github.com/qq449245884…

我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,即可看到福利,你懂的。

1

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK