EventLoop事件循环机制

发布于:2022-12-21 ⋅ 阅读:(343) ⋅ 点赞:(0)

任务执行顺序

        javascript是单线程语言,代码中所有任务都要排队执行。根据执行先后顺序不同,将任务分为同步任务和异步任务,异步任务又分为宏任务和微任务,执行顺序依次为:

  1. 同步任务
  2. 微任务
  3. 宏任务        

宏任务

  • setTimeout
  • setInterval
  • Ajax
  • DOM事件

微任务

  • Promise对象的then、catch和finally(new一个对象的过程是同步任务)
  • async/await
  • nodejs中的nextTick

async/await

  1. 用同步代码实现异步的最终解决方案
  2. async和await必须配合使用
  3. await所在任务必须等待Promise对象的函数参数的函数体有resolve成功函数或者有reject失败之后通过catch捕获异常的过程后,await的任务才结束
  4. await之前执行的代码是同步代码

事件执行过程

  1. 同步任务进入主线程
  2. 异步任务进入Event Table并注册函数,将宏任务放到Event Quene任务队列,将微任务放到微任务队列
  3. 执行主线程同步任务
  4. 将微任务队列中的微任务放入到主线程中执行
  5. 将任务队列中的宏任务放到主线程中执行 

以上过程不断循环执行的机制,即事件循环机制

示例代码

setTimeout(() => {
  console.log('1')
}, 0)
async function getUser() {
  await new Promise((resolve, reject) => {
    reject('2')
    console.log('3')
  }).catch((value) => {
    console.log(value)
    setTimeout(async () => {
      console.log('4')
      await new Promise((resolve, reject) => {
        reject('5')
        console.log('6')
      }).catch((value) => {
        console.log(value)
        setTimeout(() => {
          console.log('7')
        }, 0)
      })
      console.log('8')
      setTimeout(() => {
        console.log('end')
      }, 0)
    }, 0)
  })
  console.log('9')
  setTimeout(() => {
    console.log('10')
  }, 0)
}
async function getUser1() {
  await new Promise((resolve, reject) => {
    reject('11')
    console.log('12')
  }).catch(async (value) => {
    console.log(value)
    await new Promise((resolve, reject) => {
      reject('13')
      console.log('14')
    }).catch((value) => {
      console.log(value)
    })
    setTimeout(() => {
      console.log('15')
    }, 0)
  })
  console.log('16')
  setTimeout(() => {
    console.log('17')
  }, 0)
}
getUser()
getUser1()

  分析

  • 宏任务中的同步任务和微任务要在本队列中其他宏任务之前执行
  • 微任务和宏任务代码更像是包裹同步任务和其他任务的“容器”        

 

结果:3 12 2 11 14 9 13 16 1 4 6 5 8 10 15 17 7 end

微任务中的微任务

;(async function my() {
  await new Promise((resolve, reject) => {
    reject('1')
    console.log('2')
  }).catch(async (value) => {
    console.log(value)
    await new Promise((reslove, reject) => {
      reject('3')
    }).catch(async (value) => {
      console.log(value)
      await new Promise((reslove, reject) => {
        reject('4')
      }).catch((value) => {
        console.log(value)
      })
    })
  })
  console.log('5')
  setTimeout(() => {
    console.log('6')
  }, 0)
})()
;(async function my1() {
  await new Promise((resolve, reject) => {
    reject('7')
    console.log('8')
  }).catch((value) => {
    console.log(value)
  })
  // 先等待先执行
  console.log('9')
  setTimeout(() => {
    console.log('10')
  }, 0)
})()

分析

 结果:2 8 1 7 3 9 4 5 10 6

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到