前言
Event Loop
JavaScript 有一个主线程 main thread,和调用栈 call-stack 也称之为执行栈。所有的任务都会放到调用栈中等待主线程来执行。
JavaScript 的 Event Loop 是伴随着整个源码文件生命周期的,只要当前 JavaScript 在运行中,内部的这个循环就会不断地循环下去,去寻找 queue 里面能执行的 task。
js执行过程
- 主线程自上而下执行所有代码
- 同步任务直接进入到主线程被执行,而异步任务则进入到 Event Table 并注册相对应的回调函数
- 异步任务完成后,Event Table 会将这个函数移入 Event Queue
- 主线程任务执行完了以后,会从Event Queue中读取任务,进入到主线程去执行。
- 循环如上
宏任务(MacroTask)、微任务(MicroTask)
-
微任务优先级大于宏任务 Process.nextTick > Promise.then catch finally > MutationObserver。
-
宏任务 setTimeout、setInterval、I/O、UI Rendering > setImmediate
** 注意:someScript() 中的代码属于同步代码立即执行 resolveScript属于异步代码 **
new Promise(function(){
someScript()
}).then((){
resolveScript()
})
测试实例:
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
执行结果为: script start > script end > promise1 > promise2 > setTimeout
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, 11, 3, 10, 5, 12,
setImmediate(function(){
console.log(1);
},0);
setTimeout(function(){
console.log(2);
},0);
new Promise(function(resolve){
console.log(3);
resolve();
console.log(4);
}).then(function(){
console.log(5);
});
console.log(6);
process.nextTick(function(){
console.log(7);
});
console.log(8);
**执行结果为: 3, 4, 6, 8, 7, 5, 2, 1,