IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 一篇文章,彻底搞懂JavaScript浏览器的事件循环机制 -> 正文阅读

[JavaScript知识库]一篇文章,彻底搞懂JavaScript浏览器的事件循环机制

关于浏览器的事件循环机制,在之前的话总是感觉模模糊糊,今天特意回顾了一下,彻底搞懂它!卷!

浏览器的事件循环机制(JavaScript Event Loop)

首先,JavaScript是一门单线程的语言,异步和多线程的实现需要借助JavaScript Event Loop事件循环机制来实现的,大体包括(调用栈、任务队列,任务队列又分为宏任务和微任务

JavaScript的代码在执行过程中,除了依靠函数调用栈来搞定函数的执行顺序外话需要靠任务队列来搞定另外一些代码的执行。整个执行过程,我们称为事件循环的过程。一个线程中,事件循环是惟一的,但是任务队列可以拥有多个。任务队列又分为宏任务(macro-task)和微任务(micro-task),在最新标准中他们又被分为task和jobs。

执行宏任务,然后执行宏任务产生的微任务,若微任务在执行的过程中产生了新的微任务,则继续执行微任务;微任务执行完毕后,在回到宏任务进行下一轮的循环。

宏任务包括

  1. script标签整体代码
  2. setTimeout、setInterval、setImmediate
  3. fetch

微任务包括

  1. promise
  2. async和await
  3. process.nextTick

事件开始时,会先从全局栈开始一行一行执行,遇到函数调用会将其压入调用栈中,被压入的函数叫做帧,但函数返回后,会将函数从栈中弹出。

接下来我们直接上代码,然后一步一步拓展

<script>
    /* 以下代码的输出是什么? */
    function func1() {
      console.log(1);
    }
    function func2() {
      console.log(2);
      func1()
      console.log(3);
    }
    func2()	// 2 1 3
  </script>

请添加图片描述
分析

  1. 首先,调用func2函数,将func2压入栈中,执行它里边的代码,遇到console.log(2);,压入栈中,打印执行,输出2,然后弹出。
  2. 然后,遇到func1函数,将func1压入栈中,执行里边的代码,遇到console.log(1);,压入栈中,打印执行,输出1,然后弹出。func1函数执行完毕弹出。
  3. 最后,遇到console.log(3);,压入栈中,打印执行,输出3,弹出,func2执行完毕,弹出,此时整个调用栈清空。

所以最后的输出是2 1 3。

接着在以上代码中加上宏任务

在遇到宏任务时,会将其入队到任务队列中等待,任务队列会在调用栈清空时执行!

<script>
    function func1() {
      console.log(1);
    }
    function func2() {
      setTimeout(() => {
        console.log(2);
      }, 0);
      func1()
      console.log(3);
    }
    func2() // 1 3 2
  </script>

分析

  1. 首先执行func2函数,将其压入栈中
  2. 在遇到setTimeout、setInterval、fetch时,会先将其入队到任务队列当中
  3. 任务队列会在调用栈清空时执行,所以console.log(2)先入队等待,然后遇到func1()调用,将func1函数压入栈中,开始执行,将console.log(1)压入栈中,打印执行,输出1,然后弹出,然后弹出func1,然后将console.log(3)压入栈中,打印执行,输出3
  4. 此时调用栈已清空,任务队列中的任务会被压入栈中执行,然后输出2

在宏任务的基础上再加上微任务

Promise、async、await异步操作会在调用栈清空时立即执行,并且新加入的微任务也会被一同执行!!!

<script>
    var p = new Promise(resolve=>{
      console.log(4);
      resolve(5)
    })
    function func1() {
      console.log(1);
    }
    function func2() {
      setTimeout(() => {
        console.log(2);
      }, 0);
      func1()
      console.log(3);
      p.then(data=>{
        console.log(data);
      })
      .then(()=>{
        console.log(6);
      })
    }
    func2() // 4 1 3 5 6 2
  </script>

分析

  1. 首先,会加载Promise的构造函数,将其压入栈中,执行里边的代码,console.log(4)、resolve(5)
    完成后将其弹出栈。
  2. 之后将func2压入栈中,开始执行里边的代码,遇见宏任务,会先将它入队到任务队列中等待,然后执行func1,打印1后将其弹出,之后再打印3
  3. 紧接着就产生了微任务p.then()的方法,会先将其加入到微任务,然后瞬间执行resolve(5)、console.log(6),然后将微任务弹出后,再回到宏任务,执行延迟器console.log(2),执行完毕后弹出

所以最后的结果就是4 1 3 5 6 2

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-12 23:20:30  更:2021-10-12 23:20:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 0:30:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码