事件環(瀏覽器&node)

棧和隊列

  • 棧(Stack):是一種後進先出的數據結構,進出口在同一個端口;
function a(){
	    console.log('a')
	    function b(){
	        console.log('b');
	        function c(){
	            console.log('c');
	        }
	        c();
	    }
	    b();
	}

	a();
	// => a b c
	// 函數調用順序是a b c, 而作用域銷燬的過程依次是c b a
  • 堆(Queue):又叫隊列,是一種先進先出的數據結構,進出口在不同的端口。
 // 隊列(堆)執行時按照放置的順序依次執行
    // 先進先出
	setTimeout(function(){
	    console.log(1)
	});
	setTimeout(function(){
	    console.log(2)
	});
	setTimeout(function(){
	    console.log(3)
	});
	// => 1 2 3

瀏覽器事件環

  • 宏任務和微任務

macrotask
setTimeoutsetInterval事件script,ajax,MessageChannel,
setImmediate(IE),MessageChannel,I/O ,requestAnimationFrame
microtask
promise.then()MutationObserver

  • 執行順序
// 宏  異步1
setTimeout(() => {
    console.log('setTimeout1');
      // 微  異步
    Promise.resolve().then(data => {
        console.log('then3');
    });
},1000);
// 微  異步2
Promise.resolve().then(data => {
    console.log('then1');
});
// 微  異步3
Promise.resolve().then(data => {
    console.log('then2');
    // 宏  異步4
    setTimeout(() => {
        console.log('setTimeout2');
    },1000);
});
// 同步
console.log(2);
// 2   then1  then2 setTimeout1 then3 setTimeout2
  • 先執行棧中的內容,也就是同步代碼,所以2被輸出出來;
  • 然後清空微任務,所以依次輸出的是 then1 then2;
  • 因代碼是從上到下執行的,所以1s後 setTimeout1 被執行輸出;
  • 接着再次清空微任務,then3被輸出;
  • 最後執行輸出setTimeout2
// 宏   異步 
setTimeout(() => {
    console.log(2);
    // 微  異步
    Promise.resolve().then(() => {
        console.log(6);
    });
}, 0);
// 微  異步
Promise.resolve(3).then((data) => {
    console.log(data);  	
    return data + 1;
    // 微 異步
}).then((data) => {
    console.log(data)	
    // 宏  異步	
    setTimeout(() => {
        console.log(data + 1)	
        return data + 1;
    }, 1000)
    // 微 異步
}).then((data) => {
    console.log(data);		
});
// 3    4  undefined   2  6   5

// 宏  異步
setTimeout(() => {
    console.log(1);
    // 微  異步
    Promise.resolve().then(data => {
        console.log(2);
    });
}, 0);
// 微  異步
Promise.resolve().then(data => {
    console.log(3);
    // 宏  異步 
    setTimeout(() => {
        console.log(4)
    }, 0);
});
// 同步
console.log('start');
// start  3  1   2   4 

// 宏  異步
setTimeout(function () {
    console.log(1);
    // 微  異步
    Promise.resolve().then(function () {
        console.log(2);
    }); 
}); 
// 宏  異步
setTimeout(function () {
    console.log(3);
}); 
// 微  異步
Promise.resolve().then(function () {
    console.log(4);
}); 
// 同步
console.log(5);
//5    4     1   2   3 
// 宏  異步
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

node事件環

  • 宏任務和微任務

macrotask
setTimeout ,setInterval ,setImmediate ,I/O
microtask
promise.then ,process.nextTick

  • 執行順序
    Node中是先執行主棧中的代碼,執行完,先清空一輪微任務,再執行宏任務隊列中的第1個,把宏任務執行了,再次去清空微任務
setTimeout(()=>{
    console.log("timer1")
    Promise.resolve().then(data=>{
        console.log("then1")
    })
})
Promise.resolve().then(data=>{
    console.log("then2")
    setTimeout(()=>{
        console.log("timer2")
    })
})
Promise.resolve().then(data=>{
    console.log("then3")
})
// then2 then3 timer1 then1 timer2
setTimeout(()=>{
    console.log("timer1")
    Promise.resolve().then(data=>{
        console.log("then3")
    })
})
setTimeout(()=>{
    console.log("timer2")
})
Promise.resolve().then(data=>{
    console.log("then1")
})
Promise.resolve().then(data=>{
    console.log("then2")
})
// then1  then2 timer1 then3 timer2
// then1  then2 timer2 timer1 then3
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  9  3 11  10  5  12
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章