Eventloop(事件循環)

Event Loop即事件循環,是指瀏覽器或Node的一種解決javaScript單線程運行時不會阻塞的一種機制,也就是我們經常使用異步的原理。

JavaScript代碼的執行過程中,除了依靠函數調用棧來搞定函數的執行順序外,還依靠任務隊列(task queue)(先進先出)來搞定另外一些代碼的執行

Javascript單線程任務被分爲同步任務和異步任務,同步任務會在調用棧中按照順序等待主線程依次執行(代碼從上到下的執行),異步任務會在異步任務有了結果後,將註冊的回調函數放入任務隊列中等待主線程空閒的時候(調用棧被清空),被讀取到棧內等待主線程的執行。

一個線程中,事件循環是唯一的,但是任務隊列可以擁有多個。

任務隊列又分爲macro-task(宏任務)與micro-task(微任務),在最新標準中,它們被分別稱爲task與jobs。

macro-task大概包括:script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering。

micro-task大概包括: process.nextTick, Promise, Object.observe(已廢棄), MutationObserver(html5新特性)

setTimeout/Promise等我們稱之爲任務源。而進入任務隊列的是他們指定的具體執行任務。

來自不同任務源的任務會進入到不同的任務隊列。其中setTimeout與setInterval是同源的。

事件循環的順序,決定了JavaScript代碼的執行順序。它從script(整體代碼)開始第一次循環(即宏任務)。之後全局上下文進入函數調用棧。直到調用棧清空(只剩全局),然後執行所有的micro-task(微任務)。當所有可執行的micro-task(微任務)執行完畢之後。循環再次從macro-task(宏任務)開始,找到其中一個任務隊列執行完畢,然後再執行所有的micro-task(微任務),這樣一直循環下去。

一個簡單的例子:

setTimeout(function(){

      console.log('timeout1');

})

new Promise(function(resolve){

       console.log('promise1');

       for(var i =0; i <1000; i++) {

              i ==99&& resolve();

       }

console.log('promise2');

}).then(function(){

       console.log('then1');

})

console.log('global1')
//打印的順序
// promise1

// promise2

// global1

// then1timeout1

具體可以參考:https://www.jianshu.com/p/6a1932dbbc95      https://zhuanlan.zhihu.com/p/55511602  這二篇文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章