標籤:語言 類比 javascrip 任務 loop monit 誤差 完全 alt
javascript是一門單線程語言,為了實現主線程的不阻塞,但可以用Event Loop類比多線程操作
Event Loop中同步非同步任務執行順序:
- 所有非同步任務都是在Event Table中註冊函數,當指定的時間完成時,Event Table會將函數放入Event Queue,主線程的同步任務執行完會去Event Queue讀取對應函數,進入主線程執行。
js引擎monitoring process進程,當發現主進程執行棧為空白,會去執行Event Queue中的函數
let data = [];$.ajax({ url:url data:data, success:() => { console.log(‘發送成功!‘); }})console.log(‘代碼執行結束‘);
上面是ajax執行順序:
ajax進入Event Table,註冊回呼函數success。
執行console.log(‘代碼執行結束‘)。
ajax事件完成,回呼函數success進入Event Queue。
主線程從Event Queue讀取回呼函數success並執行。
除了廣義的同步任務和非同步任務,我們對任務有更精細的定義:
macro-task(宏任務)::setTimeout、setInterval、setImmediate、I/O、UI互動事件
micro-task(微任務):Promise、process.nextTick、MutaionObserver
console.log(‘1‘);setTimeout(function() { console.log(‘2‘); process.nextTick(function() { console.log(‘3‘); }) new Promise(function(resolve) { console.log(‘4‘); resolve(); }).then(function() { console.log(‘5‘) })})process.nextTick(function() { console.log(‘6‘);})new Promise(function(resolve) { console.log(‘7‘); resolve();}).then(function() { console.log(‘8‘)})setTimeout(function() { console.log(‘9‘); process.nextTick(function() { console.log(‘10‘); }) new Promise(function(resolve) { console.log(‘11‘); resolve(); }).then(function() { console.log(‘12‘) })})
整段代碼,共進行了三次事件迴圈,完整的輸出為1,7,6,8,2,4,3,5,9,11,10,12。
(請注意,node環境下的事件監聽依賴libuv與前端環境不完全相同,輸出順序可能會有誤差)
JavaScript執行順序Event Loop