js運(yùn)行機(jī)制(事件循環(huán) Event Loop)

在了解javascript運(yùn)行機(jī)制前 我們需要了解一下以下幾點(diǎn):

  • javascript是多線程還是單線程?

  • 一個(gè)簡(jiǎn)單的測(cè)試

  • javascript中的 同步任務(wù)與異步任務(wù)

  • javascript中的 執(zhí)行棧

  • javascript中的回調(diào)函數(shù)和事件

  • Javascript中的任務(wù)隊(duì)列

  • javascript中的Event Loop

javascript是多線程還是單線程?

JavaScript語言的一大特點(diǎn)就是單線程,也就是說,同一個(gè)時(shí)間只能做一件事。

一個(gè)簡(jiǎn)單的測(cè)試,思考一下 以下代碼 的運(yùn)行結(jié)果

function syncAndAsync() {
    console.log("1") //步驟1
    setTimeout(() => {//步驟3
      console.log("2")
    }, 1000);
    console.log("3")//步驟2
  }

運(yùn)行結(jié)果:1,3,2
為什么 是這樣的結(jié)果呢?

如果把步驟2的時(shí)間改為0秒 結(jié)果會(huì)如何呢?

請(qǐng)讀完js的運(yùn)行機(jī)制后 ,答案就很明了了。

javascript中的同步任務(wù)與異步任務(wù)

因?yàn)閖avascript是單線程的 ,所以 javascript 把運(yùn)行的任務(wù),設(shè)計(jì)了兩種 同步任務(wù)和異步任務(wù)

同步任務(wù)指的是:在主線程上排隊(duì)執(zhí)行的任務(wù),只有前一個(gè)任務(wù)執(zhí)行完畢,才能執(zhí)行后一個(gè)任務(wù);

異步任務(wù)指的是:不進(jìn)入主線程、被主線程掛起的任務(wù),只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。當(dāng)主線程 的所有同步任務(wù)執(zhí)行完后,查看該任務(wù)隊(duì)列 的事件,對(duì)應(yīng)的任務(wù) 結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。

javascript中的 執(zhí)行棧

所有同步任務(wù)都是在主線程上執(zhí)行的,這些同步任務(wù)在主線程上的執(zhí)行,這就是執(zhí)行棧。

javascript中的回調(diào)函數(shù)

回調(diào)函數(shù),就是那些會(huì)被主線程掛起來的任務(wù)。異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)主線程開始執(zhí)行異步任務(wù),就是執(zhí)行對(duì)應(yīng)的回調(diào)函數(shù)。

Javascript中的任務(wù)隊(duì)列

"任務(wù)隊(duì)列"是一個(gè)事件的隊(duì)列(也可以理解成消息的隊(duì)列),隊(duì)列中對(duì)應(yīng)的任務(wù)有了結(jié)果(比如讀取文件(io操作),請(qǐng)求遠(yuǎn)程數(shù)據(jù)等等),就在"任務(wù)隊(duì)列"中添加一個(gè)事件,表示相關(guān)的異步任務(wù)可以進(jìn)入"執(zhí)行棧"了。主線程讀取"任務(wù)隊(duì)列",就是讀取里面有那些事件。

"任務(wù)隊(duì)列"中的事件,除了IO設(shè)備的事件以外,還包括一些用戶產(chǎn)生的事件(比如鼠標(biāo)點(diǎn)擊、頁面滾動(dòng)等等)。只要指定過回調(diào)函數(shù),這些事件發(fā)生時(shí)就會(huì)進(jìn)入"任務(wù)隊(duì)列",等待主線程讀取。

javascript中的Event Loop

主線程先執(zhí)行同步任務(wù),也就是執(zhí)行棧中的 任務(wù),當(dāng)執(zhí)行完所有的執(zhí)行棧中的任務(wù)后 ,從"任務(wù)隊(duì)列"中讀取事件,然后執(zhí)行對(duì)應(yīng)可執(zhí)行狀態(tài)的異步任務(wù)(回調(diào))。這個(gè)過程是不斷循環(huán)的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為Event Loop(事件循環(huán))。

異步執(zhí)行的運(yùn)行機(jī)制步驟如下:

1,所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack),排隊(duì)執(zhí)行。
2,主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。
3,一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。那些對(duì)應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。
4,主線程不斷重復(fù)上面的第三步。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容