異步javascript
異步編程的核心: 如今 與 稍後 的部分之間的關係。
例子: 去吃飯排隊,先拿一個號,排到了手機會有消息收到。在這個時候,能夠取買點喝的。java
如今:排隊拿號 -> 買水 。
稍後:短信通知排到了,開吃!node
event loop 事件輪詢es6
咱們將事件輪詢理解成一個永動機,它一直會去找某一個隊列【就能夠理解成一個數組】裏面的是否有執行的任務,若是有,那麼會去執行。web
模擬代碼:編程
var eventLoop = []; var event; // 永遠執行 while (true) { // 檢查隊列是否有數據 // 執行一個tick if (eventLoop.length > 0) { event = eventLoop.shift(); try { event(); } catch(err) { reportError(err); // report Error stack info } } }
js引擎 遇到異步代碼塊,會將它放到【不必定是立刻】任務隊列裏面,當主線程執行完全部代碼的時候,會從這個任務隊列裏面取任務,若是有就執行。數組
setTimeout 不會將回調放在事件輪詢隊列上,定時器超時的時候,環境纔會把你的回調放進事件輪詢,這樣在將來的某個tick中將會被取出執行。promise
雖然說js是單線程,可是在事件輪詢 和 併發模型機制上,並不是是單線程。 除了主線程callstack , 還有一個專門處理回調函數或者事件的線程(在瀏覽器裏面就是webAPI,node裏面就是線程 )。外面有一個task queue,這裏就是回調等待的地方。瀏覽器
好比遇到了A , A 有一個回調,A函數執行了,A的回調放到了 另外的線程,另外的線程在知足必定條件(多是setTimeout 或者response響應)以後就會將這個回調放到 task queue 裏面, callstack [必須]clear以後會立刻去task queue 裏面一個一個執行這個隊列的代碼,執行完一個,task queue的這個就回收。併發
nice video: https://www.youtube.com/watch?v=8aGhZQkoFbQ
[大白話]: 主線程的代碼執行完畢以後,而後會去task queue(任務隊列)去執行隊列中的任務。
因此
console.log("one") setTimeout(()=>{ console.log("two") }, 0) console.log("three")
結果會是:
"one" "three" "two"
而不是one two three
。
可是ES6 引入了promise generator async 等異步概念,他們是否是也是被放到了task queque呢。。答案是否認的。
在任意特定的時刻
,一次只有一個隊列中的一個事件能夠被處理,當事件執行的時候,它能夠間接的或者直接的引起(致使)一個或者更多的後續事件。
es6引入了新的概念:job queque(工做隊列)
, Promise的異步行爲是基於job的
to be continued