js事件循环机制eventLoop

事件循环机制EventLoop

Event Loop即事件循环,是解决javaScript单线程运行阻塞的一种机制。

一、JS 执行机制

在我们学js 的时候都知道js 是单线程的如果是多线程的话会引发一个问题在同一时间同时操作DOM 一个增加一个删除JS就不知道到底要干嘛了,所以这个语言是单线程的但是随着HTML5到来js也支持了多线程webWorker 但是也是不允许操作DOM。

单线程就意味着所有的任务都需要排队,后面的任务需要等前面的任务执行完才能执行,如果前面的任务耗时过长,后面的任务就需要一直等,一些从用户角度上不需要等待的任务就会一直等待,这个从体验角度上来讲是不可接受的,所以JS中就出现了异步的概念。

二、同步任务和异步任务

同步任务: 是调用立即得到结果的任务,同步任务在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

异步任务: 是调用无法立即得到结果,需要额外的操作才能预期结果的任务,异步任务不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。异步任务执行队列中先执行宏任务,然后清空当次宏任务中的所有微任务,然后进行下一个tick如此形成循环。

异步任务又可以分为以下两种(ES6):

  • 1.宏任务
    script(整体代码)、setTimeout、setInterval、postMessage、Ajax

  • 2.微任务
    Dom操作、Promise、MutaionObserver、process.nextTick(Node.js 环境)

在这里插入图片描述

例题:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
   // 这里整体的script代码作为第一个宏任务执行
    async function Prom() {
    
    
      console.log('Y')
      await Promise.resolve() //微任务3   await之后的代码都将作为微任务进入任务队列
      console.log('X') 
    }
    setTimeout(() => {
    
     // 宏任务2
      console.log(1)
      Promise.resolve().then(()=>{
    
      // 微任务4
        console.log(2)
      })
    }, 0)
    setTimeout(() => {
    
     // 宏任务3
      console.log(3)
      Promise.resolve().then(()=>{
    
    // 微任务5
        console.log(4)
      })
    }, 0)
    Promise.resolve().then(()=>{
    
    // 微任务1
      console.log(5)
    })
    Promise.resolve().then(()=>{
    
    // 微任务2
      console.log(6)
    })
    Prom()
    console.log(0)
    // 结果 Y 0 5 6 X 1 2 3 4
  </script>
</body>
</html>

***结果分析:***首先肯定执行的是同步任务也就是调用Prom方法输出Y,然后最后一段输出的0;因为整体的script代码作为了第一个宏任务执行,此时要清空它下面的所有微任务1,2,3,由于Prom方法是在微任务1,2后面调用的,所以微任务3 在微任务1,2之后。此时一次循环结束,开始下次执行宏任务2,然后执行内部的微任务4。继续下次宏任务3,微任务5。

猜你喜欢

转载自blog.csdn.net/qq_45331969/article/details/131701902