什麼是單線程javascript
主程序只有一個線程,即同一時間片段內其只能執行單個任務。java
爲何選擇單線程?git
JavaScript的主要用途是與用戶互動,以及操做DOM。這決定了它只能是單線程,不然會帶來很複雜的同步問題。github
單線程意味着什麼?promise
單線程就意味着,全部任務都須要排隊,前一個任務結束,纔會執行後一個任務。若是前一個任務耗時很長,後一個任務就須要一直等着。這就會致使IO操做(耗時但cpu閒置)時形成性能浪費的問題。瀏覽器
如何解決單線程帶來的性能問題?併發
答案是異步!主線程徹底能夠無論IO操做,暫時掛起處於等待中的任務,先運行排在後面的任務。等到IO操做返回告終果,再回過頭,把掛起的任務繼續執行下去。因而,全部任務能夠分紅兩種,一種是同步任務(synchronous),另外一種是異步任務(asynchronous)異步
注: 當主線程阻塞時,任務隊列仍然是可以被推入任務的async
一、JavaScript 內存模型圖oop
二、JavaScript 代碼執行機制
全部同步任務都在主線程上的棧中執行。
主線程以外,還存在一個"任務隊列"(task queue)。只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件。
一旦"棧"中的全部同步任務執行完畢,系統就會讀取"任務隊列",選擇出須要首先執行的任務(由瀏覽器決定,並不按序)。
三、事件循環(EventLoop)
1.MacroTask(宏觀Task) setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering
2.MicroTask(微觀任務) process.nextTick, Promise, Object.observe, MutationObserver
規範:
Microtasks are scheduled,Microtask queue 在當前 task queue 的結尾執行。microtask中添加的microtask也被添加到Microtask queue的末尾並處理。
注: event loop的每一個turn,是由瀏覽器決定先執行哪一個task queue。這容許瀏覽器爲不一樣的task source設置不一樣的優先級,好比爲用戶交互設置更高優先級來使用戶感受流暢。
```javascript
function ELoop() { // 當前任務 let p = new Promise((resolve, reject) => { console.log("current Task") resolve(); }); let nextP;
setTimeout(() => { console.log("MacroTask_1"); nextP.then(() => { // 第一次執行時,這段代碼並無執行到。 console.log("MicroTask_promise_1"); //第一個MicroTask }) console.log("MacroTask_1 end") }, 0) // 第一個 MacroTask setTimeout(() => { console.log("MacroTask_2"); console.log("MacroTask_2 end") }, 0) // 第二個MacroTask nextP = p.then(() => { console.log("MicroTask_promise_2"); //第一個MicroTask }).then(() => { console.log("MicroTask_promise_3"); // 第二個MicroTask }) console.log("current Task end") } ELoop(); /**輸出結果: current Task current Task end MicroTask_promise_2 MicroTask_promise_3 MacroTask_1 MacroTask_1 end MicroTask_promise_1 MacroTask_2 MacroTask_2 end **/
```