你不知道的JavaScript的事件循环

news2025/1/17 1:16:16

JavaScript的事件循环

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。这也与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题

JavaScript是一门单线程执行语言。这句话直接定义了JavaScript程序执行顺序的核心,单线程意味着代码需要一行一行按照顺序执行,如果遇到一个大的循环语句或者远程加载图片资源等等语句,整个程序都会出现假死现象,直到当前的任务执行完毕,才会继续执行下面的程序。为了解决上面的问题,于是出现了同步执行、异步执行(宏任务与微任务)。

同步任务非常常见:比如上面描述的JavaScript按序执行、页面渲染、远程加载JavaScript资源等等都是同步任务。

JavaScript的执行机制

在介绍JavaScript的异步任务前,我们先来了解一下JavaScript的执行机制。

主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。为了更好的理解这句话,请看下图及代码解释。

在这里插入图片描述

console.log(1) // 用a代表
setTimeout(() => { // 用b代表
  console.log(2) // 用c代表
}); 
console.log(3); // 用d代表

上述代码执行过程如下:

  • 因为JavaScript是单线程,执行栈按顺序执行上面代码,首先遇到同步代码a并将a压进执行栈,执行输出结果,并弹出该函数语句;
  • 任务队列继续执行,遇到b异步函数setTimeout,因为是异步函数所以立马从栈中弹出,并异步执行模块(Event Queue)事件队列中,等待执行。
  • 遇到同步函数d,执行方式同上面的a。
  • 现在执行栈中为空,没有同步函数需要被执行,则取任务队列中查看,如果有任务就会压入执行栈执行。此时任务队列中有函数c,则被压入栈中执行。
  • 如果后续的c中继续存在异步任务,则会继续被放入到任务队列中等待被执行。

整个循环的过程就是Event Loop(事件循环)

宏任务与微任务

任务队列(Event Queue)有的也叫(消息队列),里面的任务可分为宏任务(Macro-task)和微任务( Micro-task ) 。

宏任务(Macro-task):

  • setTimeout
  • setInterval
  • I/O
  • UI render
  • requestAnimationFrame

微任务(Micro-task) :

  • Promise.then()
  • Async/Await
  • MutationObserver

setTimeout和setInterval

首先我们先来看setTimeout,这个api我们一般是在执行异步任务时使用,比如想在3秒后执行一个console

setTimeout(() => {
  console.log('我被执行了哈!!!');
}, 3000);

大多数情况下,这句代码执行的效果和我们期望的基本一直,即3秒后控制台输出 我被执行了哈!!!

但是基本之外就是一符合的预期,有时候我们期望500ms执行一个操作,但是确在2s之后执行了;

setTimeout(() => {
  console.log('我执行了一个操作!!!');
}, 500);

for (let index = 0; index < 10000000; index++) {
  // 这里遇到一个循环语句,大概执行了2秒
}

这里我们解释一下上面的代码执行顺序及原理:

  • 首先遇到一个异步操作,需要将console.log('我执行了一个操作!!!');放入异步队列模块中注册,然后开始定时器开始计时。
  • 接着执行同步操作for循环语句,但是该语句执行的时间稍微有那么一点长,足足执行了2秒。
  • 前面的定时器计时500毫秒已经到了,console.log('我执行了一个操作!!!');进入Event Queue中等待被放入执行栈中执行,但是不幸的是,前面的for循环执行还没结束,现在只能等待,直到for循环执行完毕才被执行;
  • 执行完毕,这时的时间已经比预期的500毫秒超出好多。

其实setIntervalsetTimeout的执行类似,这里就不在累述。唯一需要注意的一点是,对于setInterval(fn,ms)来说,我们已经知道不是每过ms秒会执行一次fn,而是每过ms秒,会有fn进入Event Queue

所以作为异步的setTimeout和setInterval的问题是,它们都不精确。它们的内在运行机制决定了实际的时间间隔,参数实际上只是指定了把要执行的代码添加到JavaScript(浏览器UI)线程队列中以等待执行的时间。如果队列前面已经加入了其他任务,那要执行的代码就要等前面的任务完成后再执行。

requestAnimationFrame

requestAnimationFramewindow的方法,告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。

requestAnimationFrame的用法其实与setTimeoutsetInterval类似,只是不需要设置时间间隔而已,且精度要优于后两者。

requestAnimationFrame的执行通常与浏览器屏幕刷新次数相匹配,保持最佳绘制效率,不会因为间隔时间过短,造成过度绘制,增加开销;也不会因为间隔时间太长,使用动画卡顿不流畅,让各种网页动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。

Promise

先要说明的是new Promise()是同步任务,而.then则是异步微任务;

关于Promise与async、await的细节,请参考你不知道的 async、await 魔鬼细节这篇文章;

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

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

相关文章

Kubernetes二进制部署 单节点

目录 1.环境准备 1.关闭防火墙和selinux 2.关闭swap 3.设置主机名 4.在master添加hosts 5.桥接的IPv4流量传递到iptables的链 6.时间同步 2.部署etcd集群 1.master节点部署 2.在node1与node2节点修改 3.在master1节点上进行启动 4.部署docker引擎 3.部署 Master 组…

麻了,同样是科班出身,学弟月薪却是我的3倍

我有个同学大学毕业&#xff0c;因为却少工作经验&#xff0c;又不愿意去正经的互联网企业做实习生&#xff0c;他嫌工资太低&#xff0c;于是进了家外包公司&#xff0c;那时候感觉待遇还可以。可现在五年过去了&#xff0c;他想跳槽却鲜有人问津。最可气的是比他晚一年毕业的…

Java中的七种设计原则

1.开闭原则 对扩展开放&#xff0c;对修改关闭。在程序需要进行扩展的时候&#xff0c;不能去修改原有的代码&#xff0c;要去实现一个热插拔的效果。简言之&#xff0c;是为了使程序的扩展性好&#xff0c;易于维护和升级。 下面是输入法设置皮肤的例子&#xff1a; // 抽象皮…

Linux入门---缓冲区模拟实现

前言 有了前面的基础我们知道c语言的缓冲区本质上就是FILE结构体的一部分&#xff0c;我们每次使用stdout将数据打印到屏幕上时&#xff0c;本质上是先将数据拷贝到FILE结构体的缓冲区中&#xff0c;然后再拷贝到内核缓冲区中也就是file结构体里面的缓冲区&#xff0c;最后再刷…

TSN网络流量记录器:一种经济高效的解决方案,用于验证汽车网络中的以太网融合。

在未来几年&#xff0c;汽车线束将从不同协议的异构网络转变为分层的同构以太网网络。在这种新情况下&#xff0c;模拟真实车辆网络的实验室测试台将需要分析工具以支持它们在车内通信验证过程中进行验证。 汽车向以太网融合原因 随着汽车内部技术变得越来越复杂&#xff0c;相…

信息调查的观念

每次做一件事前都要把这件事调查清楚&#xff0c;比如考一门科目我们要把和这门科目有关的资源都收集起来&#xff0c;然后把再从中筛选出有用的信息&#xff0c;如数值计算方法我们在考试前就可以把b站有关的学习资源网课或者前人总结的考试经验做个收集总结&#xff0c;做出对…

正则表达式 - 量词

目录 一、贪心、懒惰和占有 二、用 *、 和 ? 进行匹配 三、匹配特定次数 四、懒惰量词 五、占有量词 六、示例——括号字符串计数 {m,n} 是通用形式的量词&#xff0c;正则表达式还有三个常用量词&#xff0c;分别是 、?、*。它们的形态虽然不同于 {m,n}&#xff0c;功…

8年测试总结,项目/团队如何做自动化测试?效率价值?吐血整理...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

Linux:centos:用户基础设置》》添加,修改属性,删除,修改密码

useradd &#xff08;属性&#xff09; 用户 新建用户 usermod &#xff08;属性&#xff09; 用户 调整用户属性 userdel &#xff08;属性&#xff09; 用户 删除用户 passwd &#xff08;属性&#xff09; 用户 修改用户密…

科技云报道:国内AI大模型鏖战,上演科技罗生门

科技云报道原创。 ChatGPT的狂热从年初持续至今&#xff0c;这份狂热不仅仅来源于用户层&#xff0c;从业者、投资人以及企业可以说有过之无不及。 于是&#xff0c;这些投资人、从业者以及企业将狂热转化&#xff0c;宣布入局大模型赛道并推出相关产品。一时间&#xff0c;大…

百万年薪架构师甩出的SpringBoot趣味实战手册,GitHub标星81.6K

前言 本书内容很全面&#xff0c;囊括了Spring生态的常用技术&#xff0c;如MVC、持久化、 Redis、定时任务、消息队列、搜索引擎。本书知识讲解由浅到深&#xff0c;循序渐进&#xff0c;从Hello World讲到Spring核心原理&#xff1b;技术讲解深入浅出&#xff0c;总能以“接…

无线传感网络的节点部署覆盖及能源消耗问题研究(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 随着微电子技术的不断发展,被称作传感器节点的微小智能嵌入式设备不断的被开发出来,推动了无线传感器网络的发展。一个典型的无…

Matlab Python 如何在figure上画出表格【优化】

之前写过一次博客 Matlab&Python 如何在figure上画出表格 这次是对该博客的优化 图的结果见下相对之前有很大的进步&#xff1a; coding 在这里包含数据的绘制&#xff0c;表格的添加&#xff0c;设置表格的大小、位置等 clc clear close all; path(path,E:\new_matlab_Too…

如何获取不同分区模板的基因表达矩阵,abagen: Allen 大脑图谱遗传数据工具箱的使用笔记

abagen: Allen 大脑图谱遗传数据工具箱的使用笔记 介绍使用abagen工具箱进行标准化处理和报告代码实例——获取Schaefer2018_400Parcels_7Networks的基因表达数据基于surf空间的模板基于volume空间的模板参考文献介绍 基因表达从根本上塑造了人类大脑的结构和功能结构。像Allen…

【Linux】shell编程—数组

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、shell数组1,数组的概念2.数组的定义 二、Shell数组操作1. 获取数组的所有元素的列表2. 获取数组的所有元素下标3.取数组的元素个数4. 获取数组的某个元素的值5.…

Jmeter 压测 QPS

文章目录 1、准备工作1.1 Jmeter的基本概念1.2 Jmeter的作用1.3.Windows下Jmeter下载安装1.4 Jmeter的目录结构1.5 启动1.6 设置中文1.6.1 设置调整1.6.2 配置文件调整&#xff08;一劳永逸&#xff09; 2、Jmeter线程组基本操作2.1 线程组是什么2.2 线程组2.2.1 创建线程组2.2…

原型part学习NeurIPS2019

当我们面临具有挑战性的图像分类任务时&#xff0c;我们希望通过分解part来解释推理。每一类别的更多原型证据有助于做出最终分类决策。作者提出一种深度网络架构&#xff1a;Prototypical Part网络即ProtoPNet。网络通过寻找原型part来解释图像&#xff0c;并基于原型part进行…

同步 Swagger URL问题, 用这个插件就可解决

这个开源的 API 管理工具叫 Postcat, 支持从 Swagger URL 增量同步 API 数据到 Postcat。 使用 进入 API 模块&#xff0c;鼠标移动到主按钮加号&#xff0c;下拉看到从 Swagger 同步 URL 的选项。 填写完配置点击立即同步即可同步 API 数据。 同步规则 新的数据覆盖旧的数据…

PHP语言调用api接口,电商平台商品详情接口(封装可高并发)

PHP是为Web而生的语言&#xff0c;它提供了一些强大的内置函数来处理HTTP请求和响应。PHP为开发人员提供了一些Web开发工具&#xff0c;包括HTML、CSS、JavaScript以及各种数据库的连接和互动。与其他Web开发工具相比&#xff0c;PHP可以更加高效地运转与发挥作用。 PHP表现出…

Matlab 非线性迭代法(3)阻尼牛顿法 L-M

高斯牛顿法详解_我只是一只自动小青蛙的博客-CSDN博客 一、思想 先看一下牛顿高斯迭代法的缺点&#xff1a; 1、在计算的过程中可能会出现奇异矩阵&#xff08;不满秩&#xff09;&#xff0c;比如&#xff1a;J(k)​)TJ(k) 为病态矩阵的时候就不能得到正确的解&#xff0c;或…