进阶大神之路 之 【JS执行原理】

15 阅读3分钟

先上几道开胃菜

console.log(1);
async function async1() {
  await async2();
  console.log(2);
  await async3();
  console.log(3);
}

async function async2() {
  console.log(4);
}

async function async3() {
  console.log(5);
}

async1();
console.log(6);

执行结果:1 4 6 2 5 3

立即执行 log(1)
立即执行 async1() 
遇到第一个await,相当于new Promise,立即执行 async2 log(4)
第一个await 后面的代码相当于 then()里的回调函数,进入微任务队列
往下执行,log(6)
主线程执行完毕,微任务队列中,执行 log(2)
遇到第二个await async3,执行async3 log(5)
最后执行 log(3)
console.log(1);
setTimeout(() => {
  console.log(2);
  new Promise(function (resolve) {
    console.log(3);
    resolve();
  }).then(function () {
    console.log(4);
  });
}, 0);
new Promise(function (resolve) {
  console.log(5);
  resolve();
}).then(function () {
  console.log(6);
});
console.log(7);

执行结果 1 5 7 6 2 3 4

主线程同步任务 输出 1 5 7
setTimeout 异步-宏任务,放入宏任务队列
promise.then 异步-微任务,放入微任务队列 
主线程执行完毕,去微任务队列执行,输出6
微任务队列执行完毕,去宏任务队列,执行输出2
setTimeout中的promise立即执行,输出3then()进入微任务
待主线程执行完毕,微任务队列中的进入到主线程执行,输出4
console.log(1);
async function async1() {
  await async2();
  // 进入 微任务
  console.log(2);
  await async3();
  console.log(3);
  
  // 这段代码相当于 
  new Promise(() => { console.log(2)() }).then(function() {
      new Promise(() => { async3() }).then(function() {
          console.log(3);
      })
  })
}

async function async2() {
  console.log(4);
}

async function async3() {
  console.log(5);
}

async1();
// 宏任务
setTimeout(function () {
  console.log(6);
}, 0);

new Promise((resolve) => {
  console.log(7);
  resolve();
})
  .then(function () {
    // 微任务
    console.log(8);
  })
  .then(function () {
    // 微任务
    console.log(9);
  });
  
执行结果 1 4 7 2 5 8 3 9 6

执行主线程同步任务 打印【1】
执行async1,第一个await(等同于 new Promise),立即执行 async2,打印【4】
回到主线程执行,遇到setTimeout进入宏任务队列
主线程继续执行,遇到 new Promise立即执行,打印【7】,后面then放入微任务队列
主线程执行完毕,开始执行微任务,先进先出原则,执行async3,打印【2】,接着执行 async3,打印【5】,后面代码进入微任务队列
接着执行第二个微任务,打印【8】,后面的then进入微任务队列
接着执行第一个微任务队列,打印【3】打印【9】
微任务队列执行完毕,执行宏任务,打印【6

Event Loop

Event Loop 是计算机系统的运行机制
JavaScript 是单线程语言,代码是自上而下一行一行执行,JavaScript 语言采用这种机制解决单线程带来的一些问题

微任务、宏任务

属于JS代码范畴,JS 代码分为【同步任务】和【异步任务】
异步任务氛围【宏任务】和【微任务】

宏任务包括:
    所有同步任务、事件、定时器、网络请求、I/O事件(文件读写)等

微任务包括
    Promise.then(),Promise.catch(),Promise.finally() 、async/await

执行过程

遇到script标签,进入到第一次事件循环
遇到同步代码,立即执行
遇到宏任务,放到宏任务队列
遇到微任务,放到微任务队列
执行完所有同步代码
执行微任务代码
执行完微任务代码,清空队列
寻找下一个宏任务,进入下一次事件循环