共计 1252 个字符,预计需要花费 4 分钟才能阅读完成。
做了这么久前端,自己一直很想深入去了解了解这些玩意儿,奈何天天扑在项目上,基本没有闲余时间去想去做
面试的时候大家应该也会被问到一些浏览器执行机制的问题,我最近也去研究了一下,分享一点自己的心得。
由于 segmentfault 的限制原因,这儿大图放不上来,大家看图片的时候需要点击图片下方的 ” 查看原图 ” 才能看清除里面写的内容
写得不好,或者有意见的直接喷,不用走流程。也欢迎大佬指点
用图片的执行流程来解释一下,有图有真相
先来一张图(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 好像没找到录制的工具,后续如果找到好用的工具我把图放上来