任務分兩種:node
一種是同步任務(synchronous),另外一種是異步任務(asynchronous)。ajax
"任務隊列"是一個先進先出的數據結構,排在前面的事件,優先被主線程讀取。主線程的讀取過程基本上是自動的,只要執行棧一清空,"任務隊列"上第一位的事件就自動進入主線程。可是,因爲存在後文提到的"定時器"功能,主線程首先要檢查一下執行時間,某些事件只有到了規定的時間,才能返回主線程數組
Js 中,有兩類任務隊列:宏任務隊列(macro tasks)和微任務隊列(micro tasks)。宏任務隊列能夠有多個,微任務隊列只有一個。那麼什麼任務,會分到哪一個隊列呢?瀏覽器
微任務:process.nextTick, Promise, Object.observer, MutationObserver.
咱們上面講到,當stack空的時候,就會從任務隊列中,取任務來執行。共分3步:數據結構
更新UI渲染。多線程
Event Loop 會無限循環執行上面3步,這就是Event Loop的主要控制邏輯。其中,第3步(更新UI渲染)會根據瀏覽器的邏輯,決定要不要立刻執行更新。畢竟更新UI成本大,因此,通常都會比較長的時間間隔,執行一次更新。異步
js既然是單線程,那麼確定是排隊執行代碼,那麼怎麼去排這個隊,就是Event Loop。雖然JS是單線程,但瀏覽器不是單線程。瀏覽器中分爲如下幾個線程:async
其中JS線程和UI線程相互互斥,也就是說,當UI線程在渲染的時候,JS線程會掛起,等待UI線程完成,再執行JS線程.函數
主線程從"任務隊列"中讀取事件,這個過程是循環不斷的,因此整個的這種運行機制又稱爲Event Loop(事件循環)。oop
在進程啓動時,node便會建立一個相似while(true)的循環,每執行一次循環體的過程咱們稱爲tick,每一個tick的過程就是查看是不是否有事件等待處理,若是有,就取出事件及其相關的回調函數。若是有關聯的回調函數,就執行他們,而後進入有下一個循環體
回調函數保存在數組中,在一輪循環中數組中的回調函數所有執行完
回調函數存在鏈表中,每一次循環只執行鏈表中的一個回調函數
時間複雜度lg(n)
時間複雜度lg(n)