首頁  >  文章  >  web前端  >  理解JavaScript 事件機制的詳細分析

理解JavaScript 事件機制的詳細分析

不言
不言原創
2018-08-27 10:44:121174瀏覽

這篇文章帶給大家的內容是關於理解JavaScript 事件機制的詳細分析 ,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

按同步與非同步分

  • 先判斷JS是同步還是非同步,同步就進入主行程,非同步就進入event table

  • 非同步任務在event table中註冊函數,當滿足觸發條件後,被推入event queue

  • #同步任務進入主執行緒後一直執行,直到主執行緒空閒時,才會去event queue中查看是否有可執行的非同步任務,如果有就推入主進程中

按宏任務與微任務分(更準確)

  • macro-task(巨集任務):包含整體程式碼script,setTimeout,setInterval,setImmediate, I/O, UI rendering

  • micro-task(微任務):Promise.then,process.nextTick

許多地方把Promise標記為微任務,但這容易讓人誤以為new Promise的時候這個過程是個微任務。其實是Promsie.then、Promise.catch是微任務,new Promise的時候當做普通的生成對象來看待,所以在此我標記為Promise.then
  • 執行本輪個宏任務

    • 過程中如果遇到微任務,是同步任務就將其放到微任務的[事件隊列]裡,非同步放入微任務[事件表]中,註冊函數,達到執行條件,推入微任務[事件隊列]中(目前為止我還不知道微任務有沒有非同步任務)

    • 遇到巨集任務,是同步任務就將其放到巨集任務的[事件佇列]裡,非同步放入巨集任務[事件表]中,註冊函數,達到執行條件,推入巨集任務[事件佇列]中

  • #本輪巨集任務執行完,查看微任務的[事件佇列],並將裡面全部的微任務依序執行完,從巨集任務[事件佇列]執行下一輪巨集任務

相關知識

  • JS單線程,這線程中只有一個唯一的事件循環

  • 一個線程中,事件循環是唯一的,但是可以有多個任務隊列(微任務隊列只有一個)

  • #任務隊列分宏任務隊列與微任務隊列

#那麼問題來了,當多個巨集任務佇列時,下一趟的巨集任務該取哪一個呢?在上述方法中,我是將巨集任務都看成一個佇列的

Examples

/* example1 */
setTimeout(function () {
    console.log(1);
},7);

new Promise(function (resolve) {
    console.log(2);
    for (var i = 0; i < 10000; i++) {
        i == 99 && resolve();
    }
}).then(function () {
    console.log(3);
    setTimeout(() => {
        console.log(4);
    });
})

console.log(5);
// 2 3 5 (4 7) 后两个数字的顺序与两定时器的delayTime有关,谁先满足触发条件就先输出谁 (html5 标准中,规定delayTime >= 4ms)

/* example2 */
setTimeout(_ => console.log(4));

new Promise(resolve => {
    resolve()
    console.log(1)
}).then(_ => {
    console.log(3)
    Promise.resolve().then(_ => {
        console.log('before timeout')
    }).then(_ => {
        Promise.resolve().then(_ => {
            console.log('also before timeout')
        })
    })
})

console.log(2);
// 这个也不难,分析分析就出结果了

finally

綜上菜雞二問

  • 微任務事件佇列中存在非同步任務嘛?

  • 多個巨集任務事件佇列,下一輪巨集任務時該從哪個巨集任務事件佇列中取?

相關推薦:

細說JavaScript事件循環機制-第二講

JavaScript運行機制之事件與回呼函數

以上是理解JavaScript 事件機制的詳細分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn