React 学习笔记_10(JavaScript 中的Event loop)

Event loop

想要理解同步与非同步可以观看这个影片 : What the heck is the event loop anyway? | Philip Roberts | JSConf EU非常清楚的讲解的同步与非同步。

Stock

在程式的执行里有个东西叫做 "call stack" 负责记录着每个function执行时所需要用到的资源并记录着function执行的顺序
Example :

function a(){    return 1;}function b(){    a();}function c(){    b();}c();

先呼叫的function C, C 里面呼叫function b, b 里面呼叫 function a
http://img2.58codes.com/2024/20124767iaTXnxAkl4.png

错误 stack overflow

知名的错误stack overflow指的是stack太多东西满出来了,例如连续呼叫一个function十万次,stack没办法存放这么多动作,就会丢出stack overflow错误。

thread

虽然JaveScrip只有一个"thread" 代表着一次只能做一件事,那怎么进行非同步动作呢?虽然一个thread只能做一件事,但是却可以有多个thread,以setTimeout function来说 :

setTimeout(fn,2000);  

当2秒后呼叫fu function,浏览器就会开启另一个thread去计时,而main thread就可以往下执行下一个指令,当另一个thread计数好2秒后会将fn丢回main thread。
http://img2.58codes.com/2024/20124767P6JPagklxL.png
(图片来源 : Understanding Event Loop, Call Stack, Event & Job Queue in Javascript)

若执行了 "setTimeOut(fn,2000)"这一行程式,会先把setTimeout(fn,2000)放到stock中,由于setTimeout属于Web API,所以会将这行程式丢到另一个thread去计数2秒,然后当计数结束后会将fn放到callback queue中,而当stack清空时(其他function执行完毕),callback queue会将计数完成的fn放回stack

callback queue : 不断侦测stack是否为空,若是空的就把callback queue里面的东西丢到stack中

以程式角度来说 :

while(1){    if(callStack.length === 0 && callbackQueue.length > 0)    {        callStack.push(callbackQueue.dequeue()) // 拿出 callbackQueue ,并放到 callStack     }}

举一个影片中的範例 :

setTimeout(() => {    console.log("0ms")},0)console.log("hello");

在这边由于"setTimeout"会将计数放到另一个thread中进行计数,虽然计数的时间为0ms,但是由于进到另一个thread中,所以0ms计数完后会被放到callback queue中,而这个时候stack里面拥有"console.log("hello")" (stack并非为空),所以callback queue会等待"console.log("hello")"执行结束后才会将callback queue中的"console.log("0ms")" 放入stack中并且执行,所以会先是hello先被console出来后,0ms才会被console出来。

Step 0 :
http://img2.58codes.com/2024/20124767tRAPLtSATx.png

Step 1 : 将setTimeout放入stack中,之后将他放到Web API中计数
http://img2.58codes.com/2024/20124767Bagszzj2lF.png

Step 2 : 将"console.log("hello")"放入stack,Web API中计数完成放入callback queue
http://img2.58codes.com/2024/20124767I3NNiOAzZq.png
由于stack中还有动作(console.log("hello"))所以callback queue中的console.log("0ms")不会放到stack中。

Step 3 : Stack中为空,将callbakc queue中的console.log("0ms")放入stack并执行
http://img2.58codes.com/2024/20124767a8vOAZ4WeI.png

参考资料 :
JavaScript 中的同步与非同步(上):先成为 callback 大师吧!


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章