爲何JS是單線程?JS中的Event Loop(事件循環)?JS如何實現異步?setimeout?

 

http://www.javashuo.com/article/p-uqzofywm-em.html

https://www.jianshu.com/p/93d756db8c81

首先,請牢記2點:

(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: 

Node.js的Event Loop

1. V8引擎解析JavaScript腳本。

2. 解析後的代碼,調用Node API。

3. libuv庫負責Node API的執行。它將不一樣的任務分配給不一樣的線程,造成一個Event Loop(事件循環),以異步的方式將任務的執行結果返回給V8引擎。

4. V8引擎再將結果返回給用戶。

 

靈魂三問 : JS爲何是單線程的? 爲何須要異步? JS單線程又是如何實現異步的呢?

(1)JS爲何是單線程的?

JavaScript的主要用途主要是用戶互動,和操做DOM。若是JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另外一個線程刪除了這個節點,這時這兩個節點會有很大沖突,爲了不這個衝突,因此決定了它只能是單線程。

(2)爲何須要異步?

若是JS中不存在異步,只能自上而下執行,若是上一行解析時間很長,那麼下面的代碼就會被阻塞。 對於用戶而言,阻塞就意味着"卡死",這樣就致使了不好的用戶體驗。因此,JS中存在異步執行。

(3)單線程又是如何實現異步的呢?

 JS是經過的事件循環(event loop),理解了event loop機制,就理解了JS的執行機制

 

談談setTimeout

這段setTimeout代碼什麼意思? 咱們通常說: 3秒後,會執行setTimeout裏的那個函數

setTimeout(function(){ console.log('執行了') },3000) 

可是這種說並不嚴謹,準確的解釋是: 3秒後,setTimeout裏的函數被會推入event queue,而event queue(事件隊列)裏的任務,只有在主線程空閒時纔會執行。

因此只有知足 (1)3秒後 (2)主線程空閒,同時知足時,纔會3秒後執行該函數

若是主線程執行內容不少,執行時間超過3秒,好比執行了10秒,那麼這個函數只能10秒後執行了

相關文章
相關標籤/搜索