瀏覽器中的EventLoop
嘿,你覺得下面的程式碼執行結果是什麼呢?
console.log('start')
setTimeout( function () {
console.log('setTimeout')
}, 0 )
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('end')
複製程式碼
可以先嚐試進行如下分析
1.先將同步執行的程式碼找出,首先列印的一定是start end
2.setTimeout、Promise是否有優先順序 還是根據順序來執行?
執行一下程式碼,答案是:start、end、promise1、promise2、setTimeout
需要理解的知識點
1.執行棧
javascript是單執行緒,也就是隻有一個主執行緒,主執行緒有一個棧,每一個函式執行時都會生成新的execution context(執行上下文),執行上下文會包含一些當前函式的引數、區域性變數之類的資訊,它會被推入棧中,running execution context(正在執行的上下文)始終處於棧的頂部。當函式執行完後,它的執行上下文會從棧彈出
粟子:function bar(){
console.log('bar')
}
function foo(){
console.log('foo');
bar();
}
foo();
複製程式碼
執行過程中棧的變化:
2.巨集任務 setTimeout、setImmediate
微任務 promises、processs.nextTick、MutationObserver
3.整個最基本的Event Loop如圖所示
- queue可以看做一種資料結構,用以儲存需要執行的函式
- setTimeout註冊的函式,等到期後進入task佇列
- 其餘API註冊函式直接進入自身對應的macrotask/microtask佇列
- Event Loop繼續檢查microtask佇列是否為空,依次執行直至清空microtask佇列
- 執行macrotask佇列
Node中的EventLoop
Node.js也是單執行緒的Event Loop,但是它的執行機制不同於瀏覽器環境
根據上圖,Node.js的執行機制如下
1.V8引擎解析javascript指令碼 2.解析後的程式碼 呼叫node API 3.libuv庫負責Node API的執行。它將不同的任務分配給不同的執行緒,形成一個Event Loop(事件迴圈),以非同步的方式將任務的執行結果返回給V8引擎 4.V8引擎再將結果返回給使用者
整個最基本的Event Loop 如圖所示
練習
setTimeout(()=>{
console.log('timeout1')
Promise.resolve().then(data=>{
console.log('promise2')
})
})
Promise.resolve().then(()=>{
console.log('promise1')
setTimeout(()=>{
console.log('timeout2')
})
})
複製程式碼
let fs = require('fs')
fs.readFile('a.txt','utf-8',()=>{
setTimeout(()=>{
console.log('timeout2')
},0)
setImmediate(()=>{
console.log('setImmediate')
})
})
複製程式碼
執行一下吧 看下結果是否你想的呢???