久久久久在线观看_又色又爽又黄的免费视频播放_一区中文字幕_日韩电影在线播放

今日頭條 焦點(diǎn)資訊 營(yíng)銷之道 企業(yè)報(bào)道 淘寶運(yùn)營(yíng) 網(wǎng)站建設(shè) 軟件開(kāi)發(fā) 400電話
  當(dāng)前位置: 首頁(yè) » 資訊 » 軟件開(kāi)發(fā) » 正文

javascript事件循環(huán)機(jī)制實(shí)例詳解

放大字體  縮小字體 發(fā)布日期:2018-02-27  來(lái)源:企業(yè)800網(wǎng)  作者:新格網(wǎng)  瀏覽次數(shù):778  【去百度看看】
核心提示:Javascript有一個(gè)main thread 主進(jìn)程和call-stack(一個(gè)調(diào)用堆棧),在對(duì)一個(gè)調(diào)用堆棧中的task處理的時(shí)候,其他的都要等著。當(dāng)在執(zhí)行過(guò)程中遇到一些類似于setTimeout等異步操作的時(shí)候,會(huì)交給瀏覽器的其他模塊(以webkit為例,是webcore模塊)進(jìn)行處理,當(dāng)?shù)竭_(dá)setTimeout指定的延時(shí)執(zhí)行的時(shí)間之后,task(回調(diào)函數(shù))會(huì)放入到任務(wù)隊(duì)列之中。一般不同的異步任務(wù)的回調(diào)函數(shù)會(huì)放入不同的任務(wù)隊(duì)列之中。等到調(diào)用棧中所有task執(zhí)行完畢之后,接著去執(zhí)行任務(wù)隊(duì)列之
Javascript有一個(gè)main thread 主進(jìn)程和call-stack(一個(gè)調(diào)用堆棧),在對(duì)一個(gè)調(diào)用堆棧中的task處理的時(shí)候,其他的都要等著。當(dāng)在執(zhí)行過(guò)程中遇到一些類似于setTimeout等異步操作的時(shí)候,會(huì)交給瀏覽器的其他模塊(以webkit為例,是webcore模塊)進(jìn)行處理,當(dāng)?shù)竭_(dá)setTimeout指定的延時(shí)執(zhí)行的時(shí)間之后,task(回調(diào)函數(shù))會(huì)放入到任務(wù)隊(duì)列之中。一般不同的異步任務(wù)的回調(diào)函數(shù)會(huì)放入不同的任務(wù)隊(duì)列之中。等到調(diào)用棧中所有task執(zhí)行完畢之后,接著去執(zhí)行任務(wù)隊(duì)列之中的task(回調(diào)函數(shù))。


在上圖中,調(diào)用棧中遇到DOM操作、ajax請(qǐng)求以及setTimeout等WebAPIs的時(shí)候就會(huì)交給瀏覽器內(nèi)核的其他模塊進(jìn)行處理,webkit內(nèi)核在Javasctipt執(zhí)行引擎之外,有一個(gè)重要的模塊是webcore模塊。對(duì)于圖中WebAPIs提到的三種API,webcore分別提供了DOM Binding、network、timer模塊來(lái)處理底層實(shí)現(xiàn)。等到這些模塊處理完這些操作的時(shí)候?qū)⒒卣{(diào)函數(shù)放入任務(wù)隊(duì)列中,之后等棧中的task執(zhí)行完之后再去執(zhí)行任務(wù)隊(duì)列之中的回調(diào)函數(shù)。

從setTimeout看事件循環(huán)機(jī)制

下面用Philip Roberts的演講中的一個(gè)栗子來(lái)說(shuō)明事件循環(huán)機(jī)制究竟是怎么執(zhí)行setTimeout的。


首先main()函數(shù)的執(zhí)行上下文入棧


代碼接著執(zhí)行,遇到console.log(‘Hi’),此時(shí)log(‘Hi’)入棧,console.log方法只是一個(gè)webkit內(nèi)核支持的普通的方法,所以log(‘Hi’)方法立即被執(zhí)行。此時(shí)輸出’Hi’。


當(dāng)遇到setTimeout的時(shí)候,執(zhí)行引擎將其添加到棧中。


調(diào)用棧發(fā)現(xiàn)setTimeout是之前提到的WebAPIs中的API,因此將其出棧之后將延時(shí)執(zhí)行的函數(shù)交給瀏覽器的timer模塊進(jìn)行處理。


timer模塊去處理延時(shí)執(zhí)行的函數(shù),此時(shí)執(zhí)行引擎接著執(zhí)行將log(‘SJS’)添加到棧中,此時(shí)輸出’SJS’。


當(dāng)timer模塊中延時(shí)方法規(guī)定的時(shí)間到了之后就將其放入到任務(wù)隊(duì)列之中,此時(shí)調(diào)用棧中的task已經(jīng)全部執(zhí)行完畢。



調(diào)用棧中的task執(zhí)行完畢之后,執(zhí)行引擎會(huì)接著看執(zhí)行任務(wù)隊(duì)列中是否有需要執(zhí)行的回調(diào)函數(shù)。這里的cb函數(shù)被執(zhí)行引擎添加到調(diào)用棧中,接著執(zhí)行里面的代碼,輸出’there’。等到執(zhí)行結(jié)束之后再出棧。

小結(jié)

  • 所有的代碼都要通過(guò)函數(shù)調(diào)用棧中調(diào)用執(zhí)行。

  • 當(dāng)遇到前文中提到的APIs的時(shí)候,會(huì)交給瀏覽器內(nèi)核的其他模塊進(jìn)行處理。

  • 任務(wù)隊(duì)列中存放的是回調(diào)函數(shù)。

  • 等到調(diào)用棧中的task執(zhí)行完之后再回去執(zhí)行任務(wù)隊(duì)列之中的task。

測(cè)試

for (var i = 0; i < 5; i++) {
    setTimeout(function() {
      console.log(new Date, i);
    }, 1000);
}
console.log(new Date, i);

這段代碼是我從網(wǎng)上前不久的一篇文章80%應(yīng)聘者都不及格的 JS 面試題中找到的,現(xiàn)在我們就分析一下這段代碼究竟是怎么輸出最后文章中所說(shuō)的最后的執(zhí)行狀態(tài):

40% 的人會(huì)描述為:5 -> 5,5,5,5,5,即第 1 個(gè) 5 直接輸出,1 秒之后,輸出 5 個(gè) 5;

  1. 首先i=0時(shí),滿足條件,執(zhí)行棧執(zhí)行循環(huán)體里面的代碼,發(fā)現(xiàn)是setTimeout,將其出棧之后把延時(shí)執(zhí)行的函數(shù)交給Timer模塊進(jìn)行處理。

  2. 當(dāng)i=1,2,3,4時(shí),均滿足條件,情況和i=0時(shí)相同,因此timer模塊里面有5個(gè)相同的延時(shí)執(zhí)行的函數(shù)。

  3. 當(dāng)i=5的時(shí)候,不滿足條件,因此for循環(huán)結(jié)束,console.log(new Date, i)入棧,此時(shí)的i已經(jīng)變成了5。因此輸出5。

  4. 此時(shí)1s已經(jīng)過(guò)去,timer模塊將5個(gè)回調(diào)函數(shù)按照注冊(cè)的順序返回給任務(wù)隊(duì)列。

  5. 執(zhí)行引擎去執(zhí)行任務(wù)隊(duì)列中的函數(shù),5個(gè)function依次入棧執(zhí)行之后再出棧,此時(shí)的i已經(jīng)變成了5。因此幾乎同時(shí)輸出5個(gè)5。

  6. 因此等待的1s的時(shí)間其實(shí)只有輸出第一個(gè)5之后需要等待1s,這1s的時(shí)間是timer模塊需要等到的規(guī)定的1s時(shí)間之后才將回調(diào)函數(shù)交給任務(wù)隊(duì)列。等執(zhí)行棧執(zhí)行完畢之后再去執(zhí)行任務(wù)對(duì)列中的5個(gè)回調(diào)函數(shù)。這期間是不需要等待1s的。因此輸出的狀態(tài)就是:5 -> 5,5,5,5,5,即第1個(gè) 5 直接輸出,1s之后,輸出 5個(gè)5;

相關(guān)推薦:

js事件循環(huán)機(jī)制示例分析

以上就是javascript事件循環(huán)機(jī)制實(shí)例詳解的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!

 
關(guān)鍵詞: javascript,js,實(shí)例
 
[ 資訊搜索 ]  [ 加入收藏 ]  [ 告訴好友 ]  [ 打印本文 ]  [ 違規(guī)舉報(bào) ]  [ 關(guān)閉窗口 ]

 
0條 [查看全部]  相關(guān)評(píng)論

 
網(wǎng)站首頁(yè) | 關(guān)于我們 | 聯(lián)系方式 | 使用協(xié)議 | 版權(quán)隱私 | 網(wǎng)站地圖 | 排名推廣 | 廣告服務(wù) | 積分換禮 | 網(wǎng)站留言 | RSS訂閱 | 吉ICP備11001726號(hào)-6
企業(yè)800網(wǎng) · 提供技術(shù)支持