6

做了这么久前端,自己一直很想深入去了解了解这些玩意儿,奈何天天扑在项目上,基本没有闲余时间去想去做

面试的时候大家应该也会被问到一些浏览器执行机制的问题,我最近也去研究了一下,分享一点自己的心得。

由于segmentfault的限制原因,这儿大图放不上来,大家看图片的时候需要点击图片下方的"查看原图"才能看清除里面写的内容


写得不好,或者有意见的直接喷,不用走流程。也欢迎大佬指点


用图片的执行流程来解释一下,有图有真相

这儿加一个知识点:

栈:一种数据结构,具有的特点:先进后出(FILO—First-In/Last-Out)
队列:也是一种数据结构,具有的特点:先进先出(FIFO—first in first out)

先来一张图(ps:有没有跟我同款的输入法主题的,握个抓爪,哈哈):

图片描述

图上我们能看到我们能经常听到的几个关于浏览器执行过程的词语:

栈:顺序存放我们要执行代码
事件表:存放我们将要执行的事件(我觉得可以理解为在某些条件下执行的事件),例如图上的setTimeout内部的匿名函数、click事件(图上anonymous是匿名的意思,估计有童鞋不知道,写这儿了)
回调队列:这个应该很熟悉了,就是我们定义执行的回调函数组成的队列

然后我们一步一步来解析这个玩意儿:

图片描述

开始执行我们写的这个非常非常非常简单的js代码

我们能看到栈里面存上我们要执行的console,这儿第一部没有别的代码执行,开始执行下面的代码,狗昂!!!

图片描述

然后就是执行我们这个setTimeout函数,如上图所示,同样的先被推入执行栈,我们在定时函数里面整了个匿名函数,继续看

图片描述

如上图,咱们这儿的匿名函数进入了事件表内,然后过1000ms会进入回调队列里面,继续看

图片描述

跟上面一样,顺序执行这个console,然后把咱们在setTimeout内定义的函数放到了回调队列中,等待执行栈空闲了就会执行,继续看

图片描述

上面的图还是按照咱们熟知的顺序执行,把最后写的那个绑定的click事件放入事件表,等待咱们去点击那个button按钮触发click事件。同时在1秒计时完成后把事件表的匿名函数推入到回调队列里面。狗昂!!

图片描述

上图能看到,click事件在事件表了,咱们顺序执行的代码已经完成,然后执行栈空闲了,开始执行咱们回调队列的函数。继续看

图片描述

上图中,回调队列的函数被推到空闲的执行栈中去执行。

图片描述

上图中,执行栈执行匿名函数,我们在控制台能看到打印的console信息。

这儿还有个小知识点,栈的特性是:先入后出,后入先出。我们现在看到执行栈中,console是后于匿名函数进入栈的,所以栈弹出已经执行的函数的顺序是先弹出console,然后再弹出匿名函数。继续看

图片描述
图片描述
上图中,等待执行栈空闲了,我们去点击button执行click事件。

写到这儿我估计有杠精要说为啥要等到执行栈空了再去点那个button按钮,笑哭啊!!!我曾经遇到过这样的一个童鞋,非要跟我杠。这儿说明一下,如果执行栈还有未执行完的函数,我们点那个按钮,click事件的回调函数会按数组push的方式跟在现在回调队列数组后,然后一个一个地再被unshift到我们的执行栈去执行。

图片描述
图片描述
图片描述

上面三个图就跟前面执行匿名函数的流程一样的。

想给大家放一个完整执行的过程的gif好像没找到录制的工具,后续如果找到好用的工具我把图放上来


万年打野易大师
1.5k 声望1.1k 粉丝