js Event Loop

什么是Event Loop?

JavaScript 从 script 开始读取,然后不断循环,从 “任务队列” 中读取执行事件的过程,就是 事件循环(Event Loop)

 

Event Loop的执行过程

1.一开始整个脚本 script 作为一个宏任务执行

2.执行过程中,同步代码 直接执行,宏任务 进入宏任务队列,微任务 进入微任务队列。

3.当前宏任务执行完出队,检查微任务列表,有则依次执行,直到全部执行完毕。

4.执行浏览器 UI 线程的渲染工作。

5.检查是否有 Web Worker 任务,有则执行。 --------------------Web Worker 是运行在后台的 JS,独立于其他脚本,不会影响页面的性能。

6.执行完本轮的宏任务,回到步骤 2,依次循环,直到宏任务和微任务队列为空。

事件循环中的异步队列有两种:宏任务队列(MacroTask)和 微任务队列(MicroTask)。

 

宏任务队列可以有多个,微任务队列只有一个。

宏任务 包括:

  • script
  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI rendering

微任务 包括:

  • MutationObserver
  • Promise.then()/catch()
  •  Promise 为基础开发的其他技术,例如 fetch API
  • V8 的垃圾回收过程
  • Node 独有的 process.nextTick

 

实例1:定时器

console.log("1");

setTimeout(function () {
  console.log("2");
}, 0);

setTimeout(function () {
  console.log("3");
}, 2000);

console.log("4");

输出1 4 2 3

 

实例2:定时器+promise

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

 

实例3:综合1

setTimeout(function() {
  console.log(4);
}, 0);

const promise = new Promise((resolve) => {
  console.log(1);
  for (var i = 0; i < 10000; i++) {
    i == 9999 && resolve();
  }
  console.log(2);
}).then(function() {
  console.log(5);
});

console.log(3);

输出:1 2 3 5 4

 

实例4:综合2

setTimeout(function () {
  console.log('timeout1');
}, 1000);

console.log('start');

Promise.resolve().then(function () {
  console.log('promise1');
  Promise.resolve().then(function () {
    console.log('promise2');
  });
  setTimeout(function () {
    Promise.resolve().then(function () {
      console.log('promise3');
    });
    console.log('timeout2')
  }, 0);
});

console.log('done');

输出:

start
done
promise1
promise2
timeout2
promise3
timeout1

 

posted @ 2021-01-23 14:43  JS-Feng  阅读(72)  评论(0编辑  收藏  举报