1. 程式人生 > >事件循環究竟是什麽東東?附例題

事件循環究竟是什麽東東?附例題

set 技術 timeout nbsp 不同 分享圖片 隊列 構造函數 pan

其實事件循環Event loop的概念不難,難點在於你能判斷事件的執行順序。

還是先說說概念吧。我的理解的是JS裏面事件分為宏任務和微任務,宏任務先於微任務執行。宏任務就是整段的script啊setTimeout啊setInterval這些,微任務是Promis.then方法這些。

同時任務還可以分為同步任務和異步任務。

執行任務的時候同步任務進入主線程處理,異步任務進入Event Table並註冊回調函數,再把回調函數加到Event Queue裏面,其中宏任務和微任務不是一個廣場滴。

等到主線程裏的同步任務執行完之後再讀取Event Queue裏的任務執行。因為回調函數裏面也可能會包含不同的任務,因此會循環執行上述操作。

這就是我理解的事件循環了~但是紙上談兵是不夠的,我在網上找幾道題來增強理解吧。

console.log(‘script start‘);

setTimeout(function() {
  console.log(‘timeout1‘);
}, 10);

new Promise(resolve => {
    console.log(‘promise1‘);
    resolve();
    setTimeout(() => console.log(‘timeout2‘), 10);
}).then(function() {
    console.log(‘then1‘)
})

console.log(‘script end‘);
首先輸出整段代碼script start 遇到setTimeout添加到setTimeout隊列裏,遇到Promise執行其構造函數輸出promise,遇到第二個setTimeout加到隊列中,然後promise.then加到微任務隊列裏,遇到script end執行。主線程執行結束執行微任務,再執行setTimeout隊列。

技術分享圖片

new Promise(resolve => {
    resolve(1);
    Promise.resolve().then(() => console.log(2));
    console.log(4)
}).then(t => console.log(t));
console.log(3);
構造promise對象執行構造函數4,第一個then和第二個then依次加入微任務隊列中,執行整段script的代碼3,主線程處理完畢執行微任務,輸出2,再1.

  • setTimeout(()=>{
  • console.log(‘A‘);
  • },0);
  • var obj={
  • func:function () {
  • setTimeout(function () {
  • console.log(‘B‘)
  • },0);
  • return new Promise(function (resolve) {
  • console.log(‘C‘);
  • resolve();
  • })
  • }
  • };
  • obj.func().then(function () {
  • console.log(‘D‘)
  • });
  • console.log(‘E‘);

C E D A B


async function async1(){
console.log(‘async1 start‘)
await async2()
console.log(‘async1 end‘)
}
async function async2(){
console.log(‘async2‘)
}
console.log(‘script start‘)
setTimeout(function(){
console.log(‘setTimeout‘)
},0)
async1();
new Promise(function(resolve){
console.log(‘promise1‘)
resolve();
}).then(function(){
console.log(‘promise2‘)
})
console.log(‘script end‘)
技術分享圖片

事件循環究竟是什麽東東?附例題