JS事件eventLoop

Posted by hdj on December 22, 2023

前言

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,