什么是事件循环(Event Loop)?请谈谈它在 JavaScript 中的作用?
事件循环(Event Loop)是什么?
事件循环(Event Loop)是JavaScript运行时环境(如浏览器或Node.js)中的一个核心机制,用于处理异步操作和事件。
它负责协调代码的执行、事件的处理、以及异步操作的调度。
事件循环的基本工作原理是通过一个循环不断地从事件队列中取出事件并处理它们。
事件循环在JavaScript中的作用
事件循环的主要作用是确保JavaScript代码能够以非阻塞的方式运行。
JavaScript是单线程的,这意味着它一次只能执行一个任务。
如果没有事件循环,JavaScript代码在执行耗时操作(如网络请求或文件I/O)时,会阻塞后续代码的执行,导致页面无响应或应用卡顿。
事件循环通过以下步骤实现非阻塞执行:
- 执行同步代码:首先执行调用栈中的同步代码。
- 处理微任务:在执行完同步代码后,事件循环会检查微任务队列(Microtask Queue),并依次执行其中的所有微任务,直到微任务队列为空。常见的微任务包括
Promise
的then
回调和MutationObserver
。 - 处理宏任务:在处理完微任务后,事件循环会从宏任务队列(Macrotask Queue)中取出一个宏任务执行。常见的宏任务包括
setTimeout
、setInterval
、I/O
操作和UI渲染
。 - 重复上述步骤:执行完一个宏任务后,再次检查并执行所有微任务,然后继续从宏任务队列中取任务执行,如此循环往复。
代码示例
console.log('脚本开始');setTimeout(function() {console.log('setTimeout');
}, 0);Promise.resolve().then(function() {console.log('promise1');
}).then(function() {console.log('promise2');
});console.log('脚本结束');
输出顺序:
脚本开始
脚本结束
promise1
promise2
setTimeout
解释:
- 执行同步代码,输出
脚本开始
和脚本结束
。 setTimeout
回调被放入宏任务队列。Promise
的then
回调被放入微任务队列。- 执行微任务队列中的所有任务,输出
promise1
和promise2
。 - 执行宏任务队列中的任务,输出
setTimeout
。
日常开发中的合理化使用建议
-
合理使用
setTimeout
和setInterval
:- 避免设置过短的延迟时间,以免导致频繁的回调执行,影响性能。
- 使用
setTimeout
模拟异步操作时,确保回调函数中没有阻塞代码。
-
利用
Promise
处理异步操作:- 使用
Promise
链式调用可以更清晰地管理异步操作的顺序和依赖关系。 - 使用
async/await
语法糖简化Promise
的使用,提高代码可读性。
- 使用
-
避免长时间运行的同步代码:
- 长时间运行的同步代码会阻塞事件循环,导致页面无响应。可以将耗时操作拆分为多个小任务,使用
setTimeout
或requestAnimationFrame
进行调度。
- 长时间运行的同步代码会阻塞事件循环,导致页面无响应。可以将耗时操作拆分为多个小任务,使用
实际开发过程中需要注意的点
-
微任务和宏任务的优先级:
- 微任务的优先级高于宏任务,确保微任务在宏任务之前执行。
- 避免在微任务中执行耗时操作,以免阻塞后续宏任务的执行。
-
事件循环的性能优化:
- 避免在事件循环中执行过多的同步操作,尽量将耗时操作放在Web Worker中执行。
- 使用
requestAnimationFrame
进行动画和UI更新,确保流畅的用户体验。
-
错误处理:
- 在异步操作中添加错误处理逻辑,避免未捕获的异常影响事件循环的正常运行。
- 使用
Promise
的catch
方法或try/catch
语句捕获异步操作中的错误。
代码示例:使用async/await
处理异步操作
async function fetchData() {try {const response = await fetch('https://api.example.com/data');const data = await response.json();console.log(data);} catch (error) {console.error('Error fetching data:', error);}
}fetchData();
解释:
- 使用
async
函数和await
关键字简化异步操作的处理。 - 在
try/catch
块中捕获异步操作中的错误,确保错误不会影响事件循环的正常运行。
代码示例:避免长时间运行的同步代码
function processLargeArray(array) {return new Promise((resolve) => {let index = 0;function processNext() {if (index < array.length) {// 模拟耗时操作console.log(`Processing item ${index}`);index++;setTimeout(processNext, 0);} else {resolve();}}processNext();});
}const largeArray = Array.from({ length: 1000 }, (_, i) => i);
processLargeArray(largeArray).then(() => {console.log('Processing complete');
});
解释:
- 将耗时操作拆分为多个小任务,使用
setTimeout
进行调度。 - 避免长时间运行的同步代码阻塞事件循环,确保页面响应性。
事件循环是JavaScript运行时环境中的核心机制,负责处理异步操作和事件。
理解事件循环的工作原理和使用方法,对于编写高效、非阻塞的前端代码至关重要。
通过合理使用Promise
、async/await
、setTimeout
等工具,可以优化事件循环的性能,提升应用的响应性和用户体验。
同时,注意避免长时间运行的同步代码和合理处理错误,确保事件循环的正常运行。
相关文章:
什么是事件循环(Event Loop)?请谈谈它在 JavaScript 中的作用?
事件循环(Event Loop)是什么? 事件循环(Event Loop)是JavaScript运行时环境(如浏览器或Node.js)中的一个核心机制,用于处理异步操作和事件。 它负责协调代码的执行、事件的处理、以…...
Lua : Coroutine(协程)
Lua 协程(coroutines)是一种强大的控制结构,允许函数在执行过程中暂停并在稍后恢复。与线程不同,协程是非抢占式的,这意味着它们不会被操作系统调度,而是由程序显式地切换。协程在 Lua 中非常有用ÿ…...
【2024华为OD-E卷-200分-跳格子2】(题目+思路+JavaC++Python解析)
题目描述 在一个二维平面上,有一个 n x m 的网格,每个格子有一个非负整数。你从左上角 (0, 0) 开始,每次只能向右或向下移动,目标是到达右下角 (n-1, m-1)。 在移动过程中,你需要记录经过的格子中,最大数…...
【仓颉语言基础】语言概念、环境配置与语法解析
华为仓颉语言是一门专为分布式系统设计的现代编程语言,以简洁的语法和强大的分布式能力为核心,提供高效的资源管理和任务调度方案。本篇文章将带您从概念入手,逐步掌握环境配置与语法基础,为分布式开发奠定坚实基础。 文章目录 一…...
LeetCode - 初级算法 数组(删除排序数组中的重复项)
免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 删除排序数组中的重复项 这篇文章讨论如何从一个非严格递增的数组 nums 中删除重复的元素,使每个元素只出现一次,并返回新数组的长度。因为数组是排序的,只要是相同的肯定是挨着的,所以我们需要遍历所有数组,然…...
SpringMVC进阶(自定义拦截器以及异常处理)
文章目录 1.自定义拦截器 1.基本介绍 1.说明2.自定义拦截器的三个方法3.流程图 2.快速入门 1.Myinterceptor01.java2.FurnHandler.java3.springDispatcherServlet-servlet.xml配置拦截器4.单元测试 3.拦截特定路径 1.拦截指定路径2.通配符配置路径 4.细节说明5.多个拦截器 1.执…...
2 秒杀系统架构
第一步 思考面临的问题和业务场景 秒杀系统面临的问题: 短时间内并发非常高,如果按照秒杀的并发做相应的承载会造成大量资源的浪费。第二解决超卖的问题。 第二步 思考目前的处境和解决方案 因为秒杀系统属于短时间内的高并发问题,我们不可能使用那么…...
C++如何遍历数组vector
在C中,vector是一个可变数组。那么怎么遍历它呢?我们以for循环为例(while循环,大家自己脑补)。 方法一: 基于范围的for循环,这是C11新引入的。 std::vector<int> v {1, 2, 3, 4, 5, 6…...
ubuntu非root用户操作root权限问题-virbox挂在共享文件夹
首先讲一下,virtuallbox 挂在文件夹,操作的时候总是需要root权限,比较费劲。 这一操作其实也正对着我们在Ubuntu上的操作。 前段时间我想在ubuntu正常用户下去操作i2c,也出现了类似的问题。 后来把正常的操作加到组里面也解决了类…...
大模型推理:vllm多机多卡分布式本地部署
文章目录 1、vLLM分布式部署 docker镜像构建通信环境配置 2、其他大模型部署工具3、问题记录参考文献 单台机器GPU资源不足以执行推理任务时,一个方法是模型蒸馏量化,结果就是会牺牲些效果。另一种方式是采用多台机器多个GPU进行推理,资源不…...
WFP Listbox绑定数据后,数据变化的刷新
Listbox绑定数据通过ItemsSource来的,如果绑定的是普通的List<数据>,不会自己刷新。 使用ObservableCollection集合 解决问题的方法: 将数组替换为 ObservableCollection ObservableCollection 是专为绑定设计的集合类型,可以通知 W…...
AI + 爬虫:智能化数据采集的未来
随着人工智能(AI)技术的不断进步,传统的网络爬虫正经历一场前所未有的变革。从规则驱动到智能化演变,AI 的引入不仅提高了爬虫的效率和适应性,更为大规模数据采集提供了全新思路。本文将深入探讨 AI 与爬虫的结合&…...
人工智能知识分享第五天-正则化.损失函数案例
正则化 欠拟合与过拟合 过拟合:一个假设 在训练数据上能够获得比其他假设更好的拟合, 但是在测试数据集上却不能很好地拟合数据 (体现在准确率下降),此时认为这个假设出现了过拟合的现象。(模型过于复杂) 欠拟合:一个假设 在训…...
WebRTC的线程事件处理
1. 不同平台下处理事件的API: Linux系统下,处理事件的API是epoll或者select;Windows系统下,处理事件的API是WSAEventSelect,完全端口;Mac系统下,kqueue 2. WebRTC下的事件处理类: …...
C++软件设计模式之迭代器模式
迭代器模式是一种行为设计模式,它允许你顺序访问一个聚合对象的元素,而不暴露其底层表示。在C软件设计中,迭代器模式的主要目的是将数据的遍历行为与数据结构本身分离,使得数据结构的修改不会影响到遍历代码。 目的和意图 解耦遍…...
git reset --hard(重置到当前提交,所有未提交的更改都会被永久丢弃)
git reset --hard 是一个强大的命令,它会将你的工作目录、暂存区和当前分支的 HEAD 指针重置到指定的提交状态,所有未提交的更改都会被永久丢弃。因此,使用这个命令时需要非常小心。 基本用法 重置到当前提交(丢弃所有未提交的更…...
三分钟在你的react项目中引入tailwindcss
前言:在vite搭建的react项目中引入并使用tailwindcss 一、初始化react项目 1、创建项目 在文件夹下右键打开终端并输入命令使用vite创建项目 pnpm create vite react-tailwind选择reactjavascript,并输入命令安装依赖并启动 2、安装tailwind pnpm …...
Android Studio学习笔记
01-课程前面的话 02-Android 发展历程 03-Android 开发机器配置要求 04-Android Studio与SDK下载安装 05-创建工程与创建模拟器...
19712 数字接龙
/*我觉得重要的理解点:1.四维数组白表示一个点从另一个点沿对角线的方式进行移动,如果这个元素的值为真则表示这样的移动存在。 2.按照0->k-1的顺序移动。这个要求的实现方法也值得学习 3.count和index的含义: index表示索引,表…...
【图像去噪】论文复现:大道至简!ZS-N2N的Pytorch源码复现,跑通源码,获得指标计算结果,补充保存去噪结果图像代码,代码实现与论文理论对应!
请先看【专栏介绍文章】:【图像去噪(Image Denoising)】关于【图像去噪】专栏的相关说明,包含适配人群、专栏简介、专栏亮点、阅读方法、定价理由、品质承诺、关于更新、去噪概述、文章目录、资料汇总、问题汇总(更新中) 完整代码和训练好的模型权重文件下载链接见本文底…...
Linux-mac地址
mac地址 由6位16进制数组成。最高字节的最低位,0表示单播地址,1表示多播地址。最高字节的第二位,0表示全局地址,1表示本地地址。 单播地址:单播MAC地址用于一对一的通信模式,即从单一的源端发送到单一的目…...
旷视科技Java面试题及参考答案
讲一下进程间的通讯方式(如管道、消息队列、共享内存、Socket 等),各有什么特点? 管道(Pipe) 管道是最早出现的进程间通信方式之一,主要用于具有亲缘关系(父子进程)的进程之间通信。 特点: 半双工通信,数据只能单向流动。例如,在一个简单的父子进程通信场景中,父进…...
【无线传感网】WSN数据管理技术
文章目录 WSN数据管理的基本概念以数据为中心的WSN数据库与分布式数据库相比具有的特殊性WSN数据管理技术的研究热点 WSN数据管理的关键技术无线传感器网络数据存储结构网外集中式存储方案网内分层存储方案网内本地存储方案以数据为中心的网内存储方案 数据查询处理技术查询类型…...
硬件基础知识笔记(2)——二级管、三极管、MOS管
Part 2 二级管、三极管、MOS管 1、二级管1.1肖特基二极管和硅二极管选型比较1.2到底是什么决定了二极管的最高工作频率?1.3二极管结电容和反向恢复时间都是怎么来的 1、二级管 1.1肖特基二极管和硅二极管选型比较 肖特基二极管的优势主要在速度和压降,对…...
记录uniapp组件swiper自适应高度
在uniapp组件swiper不能自适应高度 思路: 根据传的图片,进行图片分析宽高, 根据屏幕尺寸,进行换算对应的宽高比。 最后获得图片尺寸,进行赋值。 <swiper class="swiper" :style="{ height: `${swiperheight}` + px }" @change="onSwiperC…...
Presto-简单了解-230403
presto是什么了解一下: 秒级查询引擎(不做存储),GB-PB级不依赖于yarn,有自己的资源管理和执行计划支持多种数据源:hive、redis、kafka presto架构 presto优缺点 presto优点 内存到内存的传输࿰…...
Windows Knowledge
1 GRUB简介 1.1 MBR和PBR MBR分为GRUB.MBR和DOS.MBR。 由于硬盘上扇区从偏移0到偏移62属于同一个磁道0,虽然DOS.MBR仅占用一个扇区,但是需要将DOS.MBR后面的偏移1到偏移62保留,所以磁盘上第一个分区的第一个扇区是从偏移63开始的。fbinst软件…...
【Rust自学】9.1. 不可恢复的错误以及panic!
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 9.1.1. Rust错误处理概述 Rust拥有极高的可靠性,这也延伸到了错误处理的领域。比如说在大部分情况下,Rust会迫使你…...
UE5 Debug的一些心得
1、BUG粗略可分为两类: 一种是显性的,编译直接就通不过,必须马上解决。 第二种是隐性的,新功能完成后,编译成功顺利运行,洋洋自得,而问题隐藏在幕后,测试之后才逐渐发现有问题&…...
Docker Compose 构建 EMQX 集群 实现mqqt 和websocket
EMQX 集群化管理mqqt真香 目录 #目录 /usr/emqx 容器构建 vim docker-compose.yml version: 3services:emqx1:image: emqx:5.8.3container_name: emqx1environment:- "EMQX_NODE_NAMEemqxnode1.emqx.io"- "EMQX_CLUSTER__DISCOVERY_STRATEGYstatic"- …...
通过Xshell远程连接wsl2
目录 一、WSL网络原理 二、 下载XShell 三、Ubuntu里配置ssh 1.查看是否已经安装SSH 2.安装SSH 3.修改SSH配置 4.重启ssh 5.查看ip 四、在Xshell中链接电脑 五、设置端口转发 1.设置主机端口映射到wsl2的端口 六、防火墙设置开放8989端口 方式一(推荐): 方式二:…...
产品原型设计
🤣🤣目录🤣🤣 一、Axure原型设计(Axure RP 9 )1.1 软件下载安装1.2 产品原型展示1.3 产品原型下载1.4 视频课程推荐 二、磨刀原型设计2.1 软件下载安装2.2 产品原型展示2.3 产品原型下载2.4 视频课程推荐 什…...
【二】arcgis JavaScript api 实现加载不同坐标系的底图和三维服务
提示:如果是天地图底图参考这篇文章 【一】arcgis JavaScript api 实现加载不同坐标系的底图和三维服务_arcgis js api 调用三维地图服务-CSDN博客 需求: 前端开发实现底图(wkid:3857,web墨卡托)&#x…...
使用JMeter对Linux生产服务器进行压力测试
安装 JMeter wget https://downloads.apache.org/jmeter/binaries/apache-jmeter-5.4.1.tgz tar -xzf apache-jmeter-5.4.1.tgz cd apache-jmeter-5.4.1创建 JMeter 脚本 设置中文 选择Options—>Choose Language—>选择其他语言(例如:Chinese&am…...
mapper文件的解释
<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace"com.ruoyi.system.mapper.Jianai…...
利用Claude3.5点评学习LightRAG源码
原始代码为:lightrag. 以下为两次提问记录:↓↓ 1. 请从专业程序员的角度点评这段代码↓ 我来从几个方面分析这段代码: 优点 👍 代码结构清晰 使用了 dataclass 来管理配置清晰的模块化设计,将不同功能分离到不同的存储类中使用了依赖注入…...
linux查看硬件信息
1 CPU # 查看 CPU 详细信息 # 总核数 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 cat /proc/cpuinfo# 查看物理CPU个数 cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l# 查看每个物理CPU中core的个…...
基于单片机中药存放环境监测系统的实现
基于单片机中药存放环境监测系统的实现 项目开发背景 随着现代中药的广泛应用,中药材的存储环境对其质量有着至关重要的影响。温湿度、烟雾、火灾等环境因素,若不加以控制,将会导致中药材失效或变质。因此,设计一个基于单片机的…...
从零开始开发纯血鸿蒙应用之UI封装
从零开始开发纯血鸿蒙应用 一、题引二、UI 组成三、UI 封装原则四、实现 lib_comps1、封装 UI 样式1.1、attributeModifier 属性1.2、自定义AttributeModifier<T>类 2、封装 UI 组件 五、总结 一、题引 在开始正文前,为了大家能够从本篇博文中,汲…...
0101java面经
1.Java 中有哪些垃圾回收算法? 标记 - 清除算法(Mark - Sweep) 基本原理:标记 - 清除算法是最基础的垃圾回收算法之一。它分为两个阶段,首先是标记阶段,从根对象(如栈帧中的局部变量、静态变量等引用的对…...
逐行讲解大模型流式输出 streamer 源码
目录 简介TextStreamer 基础流式输出TextIterateStreamer 迭代器流式输出本地代码模型加载并前端展示streamlit 输出显示gradio 输出显示 vllm 部署模型并前端展示streamlit 输出显示gradio 输出显示 备注 简介 本文详细讲解了大模型流式输出的源码实现,包括TextSt…...
springboot533图书管理系统(论文+源码)_kaic
摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理,然而,随着近些年信息技术的迅猛发展,让许多比较老套的信息管理模式进行了更新迭代,图书信息因为其管理内容繁杂,管理数量繁多导致手工进行处理不能满足广…...
Dell服务器升级ubuntu 22.04失败解决
ubuntu系统原版本20.04,服务器dell T40. 执行apt update后,再执行apt upgrade。 apt update执行成功,但apt upgrade执行中断,提示如下: Checking package manager Reading package lists... Done Building dependen…...
sql列转行 行转列
列转行 在 SQL 中,转换数据以按列排列的值成为按行排列的值(即所谓的“列转行”或“列转行”)是常见的数据操作需求。这个操作在不同的数据库管理系统中可以通过不同的技术手段来实现。以下是几种常见的数据库系统中实现列转行的方法&#x…...
【在Python中生成随机字符串】
在Python中生成随机字符串,你可以使用random模块结合字符串操作来实现。以下是一个简单的例子,展示了如何生成一个指定长度的随机字符串,该字符串可以包含字母(大写和小写)以及数字: import random import…...
Qt解决可执行程序的图标问题(CMake)
通常情况下,我们编译生成的可执行程序的图标长这个样子: 可以看到他的图标非常丑陋。。。 要想改变图标,你需要通过以下方式: CMakeLists.txt : cmake_minimum_required(VERSION 3.10)project(CountCode VERSION 1.0 LANGUAGE…...
婴儿四维影像生成AI人脸照片-大模型 Agent(智能体)实践
婴儿四维影像生成AI人脸照片-大模型 Agent(智能体)实践 在当今科技飞速发展的时代,大模型 Agent(智能体)作为一种创新的技术范式,正逐渐崭露头角。它依托强大的大模型能力,通过可视化设计与流程编排,以无代码或低代码的方式,为开发者提供了构建各种功能性应用程序的便…...
XIAO Esp32 S3 网络摄像头——3音视频监控
1、介绍 之前分别介绍了音频和视频的接收,本文是整合了前2篇文章,实现了音视频的同时获取。 效果: 用xiao esp35 s3自制一个网络摄像头 2、适用场景广泛 家庭安防 无论是门前监控,还是室内安全,自制摄像头可以让你轻松把握每个角落,实时查看视频流,防止任何潜在风险。…...
【GIS教程】高程点制作DEM并使用ArcgisPro发布高程服务Elevation Layer
文章目录 应用场景数据源操作步骤1、数据加载2、创建TIN3、TIN转栅格4、发布高程服务 应用场景 我有高程点和等高线数据,我需要将其发布成高程服务,在 Portal 中直接使用,或者通过 Javascript API 进行调用。 数据源 数据源为dwg格式的地形…...
C++设计模式:状态模式(自动售货机)
什么是状态模式? 状态模式是一种行为型设计模式,它允许一个对象在其内部状态发生改变时,动态改变其行为。通过将状态相关的逻辑封装到独立的类中,状态模式能够将状态管理与行为解耦,从而让系统更加灵活和可维护。 通…...