执行代码的先后顺序:

先 主任务 后 任务队列。

任务队列又分:微任务(Microtasks)、宏任务(task)

  • 微任务:先注册的任务先执行(先进先出)。比如:Promise.then 、process.nextTick
  • 宏任务:比如:整体代码<script>、ajax、定时器(比如:setTimeout)、事件(比如:onclick)、requestAnimationFrame(帧动画)、I/O(文件操作)、UI rendering(样式渲染)

任务队列既有宏任务又有微任务,先执行微任务,再执行宏任务。

主任务(主线程,执行完之后会去任务队列里读取可执行的任务进入主线程)
  ↓
任务队列:微任务(清空一次) ------> 宏任务(每执行一个清空一次微任务)
            ↑_________循环执行________|

这种循环机制叫做:事件循环(event loop)

主线程-微任务-宏任务 练习:(如何使用async、await、Promise以及各种任务的执行特点)

async function fn() {
  console.log(1);
  let b = await fn2();//b拿到return的值 = resolve()里面的值,并阻塞下面的代码。
  console.log(b);
  console.log(2)//出现在await之后,也就是2一定跟着3之后出现
};
function fn2() {
  return new Promise((resolve, reject) => {//async、await要配合Promise使用。
      console.log(9);
      setTimeout(() => {
          resolve(3)//进入宏任务,定时器谁先触发谁先执行。
      }, 1000)
  });
}
// async function fn() {
//     //function fn() {
//     console.log(1);
//     let b = await fn2();
//     console.log(2)//进入微任务,谁先进入谁先触发。
// };
// function fn2() {
//     console.log(9);
//     setTimeout(() => {
//         resolve(3)//进入宏任务,定时器谁先触发谁先执行。
//     }, 1000)
// };

setTimeout(() => {
  console.log(6)//进入宏任务
}, 500);
fn()
let a = new Promise((resolve, reject) => {
  console.log(4);
  resolve()
})
a.then(() => {
  console.log(5)//进入微任务
});
//fn()
console.log(8);
//1,9,4,8,2,5,3,6
//4,1,9,8,5,2,3,6
//注:如果await后面的函数,没有被Promise包着。 await 下面的代码会进微任务队列(谁先进入谁先执行),定时器会进宏任务队列(谁先触发谁先执行)。
//1,9,4,8,5,6,3,2
//await后面的函数被Promise包着,那么await后面的函数才会阻塞下面的函数,等await后面的函数执行完,再往下执行(只在函数体内发生)。

面试题一:

let body = document.body;
body.addEventListener('click', function () {
    Promise.resolve().then(() => {
        console.log(1);
    });
    console.log(2);
});
body.addEventListener('click', function () {
    Promise.resolve().then(() => {
        console.log(3);
    });
    console.log(4);
});

面试题二:

async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
    console.log('async2');
}
console.log('script start');
setTimeout(function () {
    console.log('setTimeout');
}, 0)
async1();
new Promise(function (resolve) {
    console.log('promise1');
    resolve();
}).then(function () {
    console.log('promise2');
});
console.log('script end');

思考?await 下面被阻断的代码,那这一部分代码是如何执行的?

  • await 后面如果是微任务(一个promise),它下面的代码就会等待这个微任务执行完,紧跟着执行。
  • await 后面如果是主任务(比如一个函数或一个表达式),其下面的代码就会等待这一批主任务执行完,最后执行。

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-01
  • 2022-12-23
  • 2021-06-21
  • 2022-12-23
  • 1970-01-01
猜你喜欢
  • 2022-12-23
  • 2021-07-18
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-05-07
相关资源
相似解决方案