event loop 事件循环机制

74 阅读1分钟

写在前面:以下是我自己对js事件循环机制的理解,基本所有类似代码都能正确书写顺序。如有用词不够准确的地方,欢迎随时指正。

附上非常典型的代码,更能够帮助理解。

image.png

重点:await后边是同步任务,赋值过程和await下边的代码都是异步任务
比较以下两种写法就能理解了

async function fn() {
   const res = await fetch('/getData');
   console.log(res);
}

function fn(){
   fetch('/getData').then((res)=>{
     console.log(res)
   })
}

1.整个script代码是一个宏任务,先执行这个宏任务。
2.同步代码放在主线程中,先执行。
3.遇到函数都会放在栈中,后进先出。
4.当执行一个函数之后,函数会从栈内移除。
-------打印: script start, Promise, async2 end, script end-------
5.微任务放在微任务队列中,宏任务放在宏任务队列中
6.最开始说的整个script宏任务执行完毕
7.检查微任务队列中是否有任务,有就执行,没有就执行下一个宏任务
8.队列是先进先出,先进入微任务队列的微任务先执行
9.执行promise1之后,又来了一个微任务then,记住秉持先进先出,后边站队去
-------打印: promise1,async1 end, promise2-------
10.检查微任务队列是否清空,空就执行下一个宏任务,非空继续清空
11.执行宏任务
-------打印: setTimeout-------

console.log('script start');

new Promise((resolve) => {
  console.log('Promise');
  resolve();
})
  .then(function () {
    console.log('promise1');
  })
  .then(function () {
    console.log('promise2');
  });

async function async1() {
  await async2();
  console.log('async1 end');
}

async function async2() {
  console.log('async2 end');
}

async1();

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

console.log('script end');

/*
打印顺序:
  script start
  Promise
  async2 end
  script end
  promise1
  async1 end
  promise2
  setTimeout
*/