事件环(浏览器&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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章