面试官:说说Event Loop事件循环、微任务、宏任务

news2024/11/17 16:17:33

前言

JS是一门单线程语言,单线程就意味着,所有的任务需要排队,前一个任务结束,才会执行下一个任务。这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的觉。为了解决这个问题,JS中出现了同步和异步。他们的本质区别是:一条流水线上各个流程的执行顺序不同。在讲JS任务执行机制前,先要了解一下什么是同步任务与异步任务。

同步任务:即主线程上的任务,按照顺序由上⾄下依次执⾏,当前⼀个任务执⾏完毕后,才能执⾏下⼀个任务。

异步任务:不进⼊主线程,⽽是进⼊任务队列的任务,执行完毕之后会产生一个回调函数,并且通知主线程。当主线程上的任务执行完后,就会调取最早通知自己的回调函数,使其进入主线程中执行。

1. 事件循环Event Loop概念介绍

  • 事件循环Event Loop又叫事件队列,两者是一个概念

事件循环指的是js代码所在运行环境(浏览器、nodejs)编译器的一种解析执行规则。事件循环不属于js代码本身的范畴,而是属于js编译器的范畴,在js中讨论事件循环是没有意义的。换句话说,js代码可以理解为是一个人在公司中具体做的事情, 而 事件循环 相当于是公司的一种规章制度。 两者不是一个层面的概念。

2. 微任务、宏任务概念介绍

  1. 微任务与宏任务就属于js代码的范畴
  2. js代码主要分为两大类: 同步代码、异步代码
  3. 异步代码又分为:微任务与宏任务

01.jpg

3. 事件循环Event Loop执行机制

  • 1.进入到script标签,就进入到了第一次事件循环.

  • 2.遇到同步代码,立即执行

  • 3.遇到宏任务,放入到宏任务队列里.

  • 4.遇到微任务,放入到微任务队列里.

  • 5.执行完所有同步代码

  • 6.执行微任务代码

  • 7.微任务代码执行完毕,本次队列清空

  • 寻找下一个宏任务,重复步骤1

    • 以此反复直到清空所以宏任务,这种不断重复的执行机制,就叫做事件循环

画了一张图来描述事件循环

02.jpg

4.易错点

(1). promise本身是一个同步的代码(只是容器),只有它后面调用的then()方法里面的回调才是微任务

04.jpg

(2). await右边的表达式还是会立即执行,表达式之后的代码才是微任务, await微任务可以转换成等价的promise微任务分析

05.jpg

(3). script标签本身是一个宏任务, 当页面出现多个script标签的时候,浏览器会把script标签作为宏任务来解析

09.jpg

参考 前端进阶面试题详细解答

看到这里,对事件循环应该有所了解了,给大家看几道面试题。

一.

1.先执行主线程上的log(1)

2.当有两个await时,只有第一个await右边的代码会立即执行log(4),后面的几行代码都会放入微任务队列中。

3.执行主线程上的log(6)

4.执行第4行至第6行的微任务

二.

08.jpg

1.先执行主线程上的1,5,7

2.主线程的同步任务执行完毕后,会先执行微任务。执行Promise的then方法里的代码,打印6

3.微任务执行完毕后,最后执行定时器里的宏任务,打印2,3,4

三.

07.jpg

1.先执行主线程上的同步代码,打印1

2.执行第9行的函数,进⼊async1内部,async1其实是声明了⼀个promise,promise是同步代码,会顺序执⾏打印async2函数里的4 ,只有.then⾥⾯的代码会加⼊微任务队列⾥,这⾥相当于执⾏了async2()之后,再将后面的代码加⼊⼀个微任务队列中。

3.回主线程中,遇到setTimeout(),加⼊到宏任务队列

4.主线程继续往后执⾏,前⾯说过,promise是同步代码,.then后⾯的回调会加⼊微任务队列,所以会打印13⾏的7

5.主线程执⾏完成,开始执⾏微任务队列内的任务,遵循先进先出的原则,打印第四⾏的2。然后接着执行第5行第二个awaite右边的代码,打印5。第6行这个时候就被加入微任务队列。

6.接着会执行第二个微任务,也就是16行代码,打印8。第17行的then这个时候也会加入微任务队列。再依次执行第6行和第17行的两个微任务,打印3和9

7.微任务执⾏结束,开始执⾏宏任务setTimeout,打印11⾏的6.

总结

  1. 所有同步任务都在主线程上执行,形成一个执行栈(call stack)。
  2. 遇到异步任务, 进入异步处理模块并注册回调函数; 等到指定的事件完成(如ajax请求响应返回, setTimeout延迟到指定时间)时,异步处理模块会将这个回调函数移入异步任务队列。
  3. 当栈中的代码执行完毕,执行栈中的任务为空时,主线程会先检查微任务队列中是否有任务,如果有,就将微任务队列中的所有任务依次执行,直到微任务队列为空; 之后再检查宏任务队列中是否有任务,如果有,则取出第一个宏任务加入到执行栈中,之后再清空执行栈,检查微任务,以此循环,直到全部的任务都执行完成。
    以上就是我对JS执行原理的一些整理和理解,希望能给读者带来一些帮助。如果有理解错误或表述不当的地方,请指正。

最后再给大家出一道题,可以把答案留在评论区

10.jpg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/149709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SOLIDWORKS有哪些好用的插件丨慧德敏学

SOLIDWORKS软件本身就带有很多插件,比如ToolBox、motion、routing、simulation等,都是直接嵌入到软件内部使用的。同时由于其API接口是完全开放的,因此还支持第三方插件的使用,SW第三方插件有很多,常用的有比如SolidKi…

React源码解读之ReactFiber

开始之前,先讲一下该文章能帮你解决哪些问题? facebook为什么要使用重构ReactReact Fiber是什么React Fiber的核心算法 - react是如何中断重启任务的react fiber部分源码简化版 前言 该文章涉及的源码部分基于React v17.0.2 why React Fiber 浏览器…

Spring常见面试题

Spring面试问题汇总①⭐Spring是什么对AOP的理解⭐对IOC的理解⭐如何实现IOC容器SpringBoot、SpringMVC、Spring的区别⭐⭐ApplicationContext和BeanFactory的区别⭐⭐⭐SpringBean的生命周期⭐⭐解释下Spring支持的几种bean的作用域⭐⭐Spring框架中的单例bean是线程安全的吗&…

数据库视图注意事项

视图(view)是一种虚拟存在的表,其内容由查询定义 本身并不包含数据。 它是作为一个select语法查询到的结果集,以此为基表创建的一张虚拟表 基表 行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成 …

【ReadPaper学术交流会】结构重参数化

提出结构重参数化的论文RepVGG 重参数化已经用在了各个领域的各个方面:比如YOLO-V6,YOLO-V7,可以autoperform YOLO-V6和YOLO-V7的一个PP-YOLO 1 我们想要一个像VGG一样的全是3*3卷积,一卷到底的结构,这样的结构并行度高、速度快而且省显存。…

剑指offer----C语言版----第十三天

目录 1. 删除链表的节点 1.1 题目描述 1.2 Leetcode解题的思路一(双指针) 1.3 Leetcode解题的思路二(单指针) 1.4 剑指offer上的原题 1. 删除链表的节点 原题链接:剑指 Offer 18. 删除链表的节点 - 力扣&#xff…

【python】类型约束(类型提示的作用)

文章目录前言一、类型系统1.动态类型2.静态类型3.鸭子类型二、变量注解1.变量注解的语法2.注解鸭子类型三、复杂(复合型)变量的注解1.引入2.难题3. Any的妙用4.类型变量5.类型Optional总结前言 python是一种解释型强类型动态语言python3.5以前是没有类型…

【Python】基于高德地图API的坐标转换函数

【Python】基于高德地图API的坐标转换函数 API申请: lbs.amap.com/api/webservice/guide/api/convert/产品介绍 坐标转换是一类简单的HTTP接口,能够将用户输入的非高德坐标(GPS坐标、mapbar坐标、baidu坐标)转换成高德坐标。 …

【学习笔记之Linux】权限之目录权限与默认权限

权限概念 一件事是否允许被谁“做”,这就是权限。权限 用户 文件属性。   在Linux上,用户分为普通用户和root。root是超级管理员 ≈ 天王老子,只能够有一个。root的命令提示符是#;普通用户通过root创建,可以有多个…

【Android安全】Protobuf原理与解析

protobuf 简介 抓包时看到header中有这个: content-type: application/x-protobuf说明包的content是以protobuf格式编码的 关于protobuf的介绍,可以参考: https://techkranti.com/what-is-protobuf-explained-for-hackers/ protobuf 的背…

C++——类和对象(一)

目录 一. 面向过程和面向对象 二. 类的引入 三. 类的定义 1.结构 2.类的作用域 3.类的两种定义方式 四. 类的访问限定符及封装 1.引入 2.访问限定符 3.封装 五. 类的实例化 六. 类对象模型 七. this指针 1.this指针的引出 2.this指针的特性 一. …

JavaScript设计模式之面向对象编程

为了深入地学习 javascript ,奔着一名标准 Web 开发人员的标准,想要深入了解一下面向对象的编程思想,提高自己模块化开发的能力,编写可维护、高效率、可拓展的代码,最近一直拜读 《JavaScript设计模式》 ,对…

【LeetBook】二叉树

参考资料:LeetBook / 二叉树 前言 差不多的解题思路就是dfs能够解决,其次就是bfs。 主要是递归的解法。 一刷就是了解了 解题的 思路 后序再补一些二叉树的题再刷一刷 目录树的介绍树的遍历前序遍历中序遍历后序遍历层序遍历(广度优先搜索)递归解决问题“…

【FPGA】中值滤波处理BMP图片

文章目录一、中值滤波二、BMP图片格式三、功能实现1.代码设计思路2.shift IP核3.代码实现四、结果测试参考博客一、中值滤波 中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。 中值滤波是基于排序统计理论…

【GO】K8s 管理系统项目[API部分--Ingress]

K8s 管理系统项目[API部分–Ingress] 1. 接口实现 service/dataselector.go import ("sort""strings""time"appsv1 "k8s.io/api/apps/v1"corev1 "k8s.io/api/core/v1"nwv1 "k8s.io/api/networking/v1" )// Ing…

JavaScript client screen offset scroll

文章目录JavaScript client screen offset scrollclientX和clientY、offsetX和offsetY、screenX和screenY、pageX和pageYclientWidth、offsetWidth、scrollWidthwindow.outerWidth、window.innerWidth、document.documentElement.clientWidthJavaScript client screen offset s…

【开发工具】Gradle的安装 与 配置环境变量

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ Gradle安装配置教程一、安装Gradle二、配置环境…

C++: Essential C++ 读书笔记:面向过程编程:调用函数。

1:传值和传址区别 按值传递: 在调用函数中将原函数的值拷贝一份过去给被调用的函数,在被调用函数中对该值的修改,不会影响原函数的值。值传递,变量赋值,修改变量的值------修改的是新地址(复制地…

智能家居加速落地,景联文科技提供数据采集标注服务

“以AI驱动智能家居,智能家庭助手和智能家居安防同向发展的智能物联网是目前主流趋势。高质量的标注数据能够高效训练算法,加速应用落地。景联文科技为相关企业提供、智能语音助手、人脸识别、指纹识别门禁系统、非法闯入检测、扫地机器人智能终端控制等…

临床资料研究中的风险因素评估相关指标

前言 写这篇文章是因为最涉及的医学相关的项目比较多,有些常常遇到的概念容易混淆,在这里着重区分一下。(感谢广大学霸的分享) 1. Ratio 与Rate 的区别 Ratio:表示相对比,简单理解为一个数值相对于另一个…