(1) JS是單線程語言segmentfault
(2) JS的Event Loop是JS的執行機制。異步
Event Loop (事件循環):函數
只要主線程空了,就去讀取「任務隊列」,從任務隊列中讀取事件,這個過程是循環不斷的,因此整個的這個運行機制叫 Event Loop。oop
主線程運行的時候,產生堆(head)和棧(stack),棧中的代碼(同步任務)調用各類外部API,它們在「任務隊列」(異步任務)中加入各類事件(click, load, done 等), 只要棧中的代碼(同步任務)執行完畢,主線程就會去讀取「任務隊列」(異步任務),依次去執行那些事件所對應的回調函數。ui
除了廣義的同步任務和異步任務,咱們對任務更準確的劃分方式是:lua
Macrotask (宏任務):spa
包括總體代碼script線程
etImmediate:把回調函數放在事件隊列的尾部3d
setTimeout:定時器code
setInterval:定時器
Microtask 微任務):
process.nextTick:把回調函數放在當前執行棧的底部
Promise:
按照這種分類方式:JS的執行機制是:
重複以上2步驟,就是更爲準確的JS執行機制了。
Node.js的Event Loop:
1. V8引擎解析JavaScript腳本。
2. 解析後的代碼,調用Node API。
3. libuv庫負責Node API的執行。它將不一樣的任務分配給不一樣的線程,造成一個Event Loop(事件循環),以異步的方式將任務的執行結果返回給V8引擎。
4. V8引擎再將結果返回給用戶。
(1)JS爲何是單線程的?
JavaScript的主要用途主要是用戶互動,和操做DOM。若是JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另外一個線程刪除了這個節點,這時這兩個節點會有很大沖突,爲了不這個衝突,因此決定了它只能是單線程。
(2)爲何須要異步?
若是JS中不存在異步,只能自上而下執行,若是上一行解析時間很長,那麼下面的代碼就會被阻塞。 對於用戶而言,阻塞就意味着"卡死",這樣就致使了不好的用戶體驗。
因此,JS中存在異步執行。
JS是經過的事件循環(event loop),理解了event loop機制,就理解了JS的執行機制
這段setTimeout代碼什麼意思? 咱們通常說: 3秒後,會執行setTimeout裏的那個函數
setTimeout(function(){ console.log('執行了') },3000)
可是這種說並不嚴謹,準確的解釋是: 3秒後,setTimeout裏的函數被會推入event queue,而event queue(事件隊列)裏的任務,只有在主線程空閒時纔會執行。
因此只有知足 (1)3秒後 (2)主線程空閒,同時知足時,纔會3秒後執行該函數
若是主線程執行內容不少,執行時間超過3秒,好比執行了10秒,那麼這個函數只能10秒後執行了