js代碼執(zhí)行順序,事件執(zhí)行和循環(huán)機(jī)制

單線程

js是單線程的,意味著他同一時(shí)間只能做一件事,也就是說所有的任務(wù)代碼需要排隊(duì)來執(zhí)行,一個(gè)任務(wù)完成之后才能開始下一個(gè)任務(wù)。
任務(wù)的排隊(duì)被稱作消息隊(duì)列。
重復(fù)執(zhí)行消息隊(duì)列中的任務(wù)的這一操作被稱作事件循環(huán)。

我們的js代碼從上往下執(zhí)行,但是難免會(huì)有一些異步操作,例如發(fā)起ajax請(qǐng)求,使用定時(shí)器操作。那么遇到異步操作時(shí)js是怎么處理的呢?

來看下以下代碼:

    console.log("a")
    let r = new Promise(function (resolve, reject) {
      console.log("b");
      resolve()
    });
    r.then(() => console.log("c"));
    setTimeout(() => { console.log("d") }, 0)
    setTimeout(() => { console.log("e") }, 1000)
    console.log("f")

如果不能在短時(shí)間得出準(zhǔn)確的結(jié)論,那么就需要深入了解js中的事件執(zhí)行機(jī)制了。

宏任務(wù)和微任務(wù)

對(duì)于消息隊(duì)列中的任務(wù),分為兩類:

  • 宏任務(wù)(macrotask ):setTimeout、setInterval
  • 微任務(wù)(microtask):promise

宏任務(wù)中包含了微任務(wù),一個(gè)宏任務(wù)執(zhí)行完成,開始下一個(gè)宏任務(wù)。

image.png

就拿上面代碼來說:

  1. 開始執(zhí)行,發(fā)現(xiàn)了一些代碼,放進(jìn)一個(gè)宏任務(wù)中
  2. 先執(zhí)行a
  3. 執(zhí)行b
  4. 發(fā)現(xiàn)異步操作then,屬于微任務(wù),把他添加進(jìn)當(dāng)前宏任務(wù)中的微任務(wù)的隊(duì)列
  5. 發(fā)現(xiàn)定時(shí)器d,setTimeout屬于宏任務(wù),添加到宏任務(wù)的隊(duì)列
  6. 發(fā)現(xiàn)定時(shí)器e,setTimeout屬于宏任務(wù),添加到宏任務(wù)的隊(duì)列
  7. 執(zhí)行f
  8. 代碼都已經(jīng)執(zhí)行完成,開始執(zhí)行微任務(wù)隊(duì)列,打印出c
  9. 微任務(wù)隊(duì)列執(zhí)行完成,開始執(zhí)行下一個(gè)宏任務(wù)隊(duì)列
  10. 直接打印出d,沒有其他微任務(wù),開始執(zhí)行下一個(gè)宏任務(wù)隊(duì)列
  11. 打印出e,所有宏任務(wù)執(zhí)行完成
?著作權(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)容