zoukankan      html  css  js  c++  java
  • 浏览器中的事件循环

    浏览器中的事件循环是怎么进行的?

    先看以下代码

    setTimeout(()=>{
      console.log('s1')
      Promise.resolve().then(()=>{
        console.log('s2')
      })
      Promise.resolve().then(()=>{
        console.log('s3')
      })
    })
    Promise.resolve().then(()=>{
      console.log('p1')
      setTimeout(()=>{
        console.log('s2')
      })
      setTimeout(()=>{
        console.log('s3')
      })
    })
    

    上面的代码执行结果是怎么样的?
    具体过程我们进行下面的分析

    浏览器中事件分为宏任务和微任务

    • setTimeout被归为宏任务,Promise.then则归为微任务

    • 浏览器对宏任务和微任务的执行顺序是有规则的

      • 优先会将同步任务加入队列,微任务加入微任务队列,宏任务加入宏任务队列
      • 优先清空微任务队列,清空微任务后,执行下一个宏任务
      • 宏任务执行完成后,会再次去清空微任务队列,因为在宏任务中可能存在微任务,会被加入微任务队列
      • 再次清空了微任务队列后,会继续重复执行下一个宏任务然后清空微任务队列,直到所有队列都被清空
    • 上面代码会按照以下步骤进行事件循环

      1. 首先浏览器会按从上到下的顺序执行所有同步代码,把宏任务和微任务分别放到不同的队列中
        上面代码中t1和p1是同步的,t1是宏任务,放到宏任务队列,p1是微任务,放到微任务队列

      1. 浏览器会优先执行微任务队列中的任务,所以p1会优先执行,此时p1被首先输出

      1. p1输出后,在微任务中发现还有两个宏任务s2和s3,这两个任务则被追加到宏任务队列中

      1. 微任务p1执行完成,弹出队列。此时微任务列队中没有任务了,开始执行宏任务队列中的第一个任务s1,此时输出s1,同时发现s1中还有两个微任务p2,p3,这两个任务则被按顺序添加到微任务队列中

      1. 此时s1执行完成,弹出队列,将开始执行微任务队列中的任务

      1. 此时微任务队列中有p2和p3两个任务,按照顺序执行,则会输出p2,p3,同时p2、p3弹出队列

      1. 此时微任务队列被清空,又会执行宏任务队列中的下一个宏任务,即s2,同理,s3与s2一样,两个任务按顺序依次输出s2、s3并弹出队列

      1. 最终结果就是依次输出p1、s1、p2、p3、s2、s3
  • 相关阅读:
    html-----vedio标签(HTML5新标签VIDEO在IOS上默认全屏播放)
    JS---控制键盘事件
    js事件监听-addEventListener (w3c标准) 和 attachEvent(ie)
    html5 -----audio标签
    花点时间搞清top、clientTop、scrollTop、offsetTop
    vue手机端横屏竖屏切换
    spring事务
    跨域
    java8 lambda 与 stream
    vueAdmin使用动态路由时踩坑
  • 原文地址:https://www.cnblogs.com/MissSage/p/15063951.html
Copyright © 2011-2022 走看看