当前位置: 首页 > article >正文

【前端分享】JavaScript异步编程详解!

JavaScript 的异步编程是其核心特性之一,主要用于处理非阻塞操作(如网络请求、文件读写、定时任务等)。由于 JavaScript 是单线程的,异步机制可以避免代码阻塞,提高性能和用户体验。以下是 JavaScript 异步编程的核心概念和实现方式:


 1. 异步编程的必要性 

  • 单线程限制:JavaScript 只有一个主线程,同步代码会阻塞后续操作。
  • 非阻塞需求:处理耗时操作(如网络请求、I/O)时,异步编程允许代码继续执行,待操作完成后通过回调通知。

 2. 实现异步的常见方式 

2.1 回调函数(Callback)
  • 基础机制:将函数作为参数传递,在异步操作完成后调用。
  • 示例:
    setTimeout(() => {console.log("延迟1秒执行");
    }, 1000);
    
  • 问题:多层嵌套会导致“回调地狱”(Callback Hell),代码难以维护。
    fs.readFile('file1.txt', (err, data1) => {fs.readFile('file2.txt', (err, data2) => {// 更多嵌套...});
    });
    

2.2 Promise
  • 设计目的:解决回调地狱,提供链式调用(.then().catch())。
  • 三种状态:pending(等待)、fulfilled(成功)、rejected(失败)。
  • 示例:
    const fetchData = () => {return new Promise((resolve, reject) => {setTimeout(() => resolve("数据加载成功"), 1000);});
    };fetchData().then(data => console.log(data)).catch(error => console.error(error));
    
  • 链式调用:
    fetchData().then(data => processData(data)).then(result => console.log(result)).catch(error => handleError(error));
    
  • 静态方法:
    • Promise.all():等待所有 Promise 完成。
    • Promise.race():取最先完成的 Promise 结果。

2.3 Async/Await
  • 语法糖:基于 Promise,用同步写法处理异步操作。
  • 规则:
    • async 标记的函数返回 Promise。
    • await 后跟 Promise,暂停执行直到 Promise 完成。
  • 示例:
    async function loadData() {try {const data = await fetchData();console.log(data);} catch (error) {console.error(error);}
    }
    loadData();
    
  • 优势:代码更简洁,错误处理更直观(try/catch)。

2.4 事件监听(Event Emitters)
  • 适用场景:如浏览器 DOM 事件、Node.js 的 EventEmitter
  • 示例:
    // 浏览器中的点击事件
    button.addEventListener('click', () => {console.log("按钮被点击");
    });
    

2.5 Generator + Yield
  • 特性:通过 function* 和 yield 暂停函数执行,需配合自动执行器(如 co 库)。
  • 示例:
    const co = require('co');function* asyncTask() {const data1 = yield fetchData1();const data2 = yield fetchData2(data1);return data2;
    }co(asyncTask).then(result => console.log(result));
    

 3. 事件循环(Event Loop)

JavaScript 通过事件循环处理异步任务,分为以下步骤: 

1、 调用栈(Call Stack):执行同步代码。 

2、 任务队列(Task Queue):存放宏任务(如 setTimeoutsetInterval)。

3、 微任务队列(Microtask Queue):存放微任务(如 Promise 的 .then()queueMicrotask)。

  • 执行顺序:同步代码 → 微任务 → 宏任务。

 4. 最佳实践 

1、 避免回调地狱:优先使用 Promise 或 Async/Await。 

2、 错误处理:Promise 用 .catch(),Async/Await 用 try/catch。 3、 并行优化:使用 Promise.all() 加速多个独立异步操作。 

4、 资源管理:用 finally 清理资源(如关闭文件)。


 5. 示例对比 

回调 vs Promise vs Async/Await
// 回调
getData((data) => {processData(data, (result) => {saveResult(result, () => {console.log("完成");});});
});// Promise
getData().then(processData).then(saveResult).then(() =>console.log("完成")).catch(handleError);// Async/Await
asyncfunction workflow() {
try {const data = await getData();const result = await processData(data);await saveResult(result);console.log("完成");} catch (error) {handleError(error);}
}

 总结 

  • 简单异步:回调或 Promise。
  • 复杂流程:Async/Await 提供更清晰的代码结构。
  • 性能关键:合理使用 Promise.all() 或 Web Workers。

理解 JavaScript 的异步机制和事件循环是成为高级开发者的关键一步。

·······END·······

  喜欢的话可以点个赞关注博主哦!!! 

相关文章:

【前端分享】JavaScript异步编程详解!

JavaScript 的异步编程是其核心特性之一,主要用于处理非阻塞操作(如网络请求、文件读写、定时任务等)。由于 JavaScript 是单线程的,异步机制可以避免代码阻塞,提高性能和用户体验。以下是 JavaScript 异步编程的核心概…...

工厂模式(简单工厂,工厂方法,抽象工厂)

工厂模式 工厂模式是java中最常用的设计模式,主要是用来完成对象的创建,使得对象创建过程和对象使用过程分离。 简单来说是取消对象创建者和使用者的耦合,简化new 对象的创建。 优势 :对象的属性创建完整。 缺点: 创建…...

Unity Internal-DeferredShading 分析

1. 延迟渲染的原理 延迟渲染主要包含了两个Pass。在第一个Pass中,我们不进行任何光照计算,而是仅仅计算哪些片元是可见的,这主要是通过深度缓冲技术来实现,当发现一个片元是可见的,我们就把它的相关信息存储到G缓冲区…...

嵌入式面试题:C 语言核心考点经典例题

引言 在嵌入式系统开发的面试中,常常会考察候选人对 C 语言基础知识的掌握程度。以下将详细分析几道常见的嵌入式面试题,包括解题步骤、涉及的知识点以及相关拓展。 题目 1 main() {unsigned char z0;unsigned char x100;unsigned char y10;z (~x)*(…...

Axure RP9教程 【数据传输】(页面值传递)| 作用域 :全局变量、局部变量

文章目录 引言作用域:全局变量作用域>局部变量作用域I 基于全局变量实现一个简单的登陆操作设置变量值的交互动作打开链接的交互动作接收并显示变量值注意点see also共享原型引言 全局变量在交互效果作用是页面值传递 作用域:全局变量作用域>局部变量作用域 全局变量…...

IBM Rational Software Architect安装感受及使用初体验

1 安装感受 最近准备用UML 2.0绘制模型图。在读UML创始人之一Grady Booch写的书《Object-Oriented Analysis and Design with Applications》(第3版)1时,发现书中用的UML工具之一为IBM Rational Software Architect(RSA&#xff…...

VRRP学习

虚拟路由器冗余技术【三层技术】:网关冗余VRRP设计了VRRP组的概念,在一个 VRRP 组中,多台路由器共同构成一个虚拟路由器。这个虚拟路由器拥有一个虚拟 IP 地址【VRRP-ID默认是8位二进制,范围是0~255,用以标识和区别不同…...

C_内存 内存地址概念

1. 计算机内存的基本概念 计算机的内存(RAM,随机存取存储器)是用来存储程序运行时的数据和指令的地方。内存被划分为许多小单元,每个单元有一个唯一的地址,这些地址从0开始编号。 内存单元:每个内存单元通…...

GPT-5、o3和o4-mini即将到来

原计划有所变更: 关于我们应有何期待的一些零散想法。 深度研究(Deep Research)确实强大但成本高昂且速度较慢(当前使用o3模型)。即将推出的o4-mini在性能上可能与o3相近,但将突破这些限制,让全球用户——甚至免费用户(尽管会有速率限制)——都能用上世界顶级AI研究助…...

C#MVC项目引用Swagger的详细步骤

目录 一、安装Swagger依赖包二、配置Swagger服务三、启用XML注释四、调整启动配置五、验证与访问常见问题解决 以下是基于ASP.NET Core项目集成Swagger的详细步骤(已适配当前项目结构): 一、安装Swagger依赖包 通过NuGet安装 右键点击项目…...

golang 对象池sync.Pool

Golang中的sync.Pool是什么? sync.Pool 是 Go 标准库中提供的一个对象池(Object Pool)实现,用于缓存和复用临时对象,以减少内存分配和垃圾回收(GC)的压力。它的主要特点是: 临时对…...

聚焦AI与大模型创新,紫光云如何引领云计算行业快速演进?

【全球云观察 | 科技热点关注】 随着近年来AI与大模型的兴起,云计算行业正在发生着一场大变局。 “在2025年春节期间,DeepSeek两周火爆全球,如何进行私域部署成了企业关心的问题。”紫光云公司总裁王燕平强调指出,AI与…...

去重新闻数据中重复的正文内容(body 字段),并把唯一的新闻内容保存到一个新的 JSON 文件中

示例代码: import os import json import nltk from tqdm import tqdmdef wr_dict(filename,dic):if not os.path.isfile(filename):data []data.append(dic)with open(filename, w) as f:json.dump(data, f)else: with open(filename, r) as f:data json.l…...

解决前后端时区不一致问题

前后端时区不一致导致: 》数据不显示在前端 》页面显示时间有误 》一些对时间有要求的方法,无法正确执行,出现null值,加上我们对null值有判断/注解,程序就会报错中断,以为是业务逻辑问题,其实…...

有哪些反爬机制可能会影响Python爬取视频?如何应对这些机制?

文章目录 前言常见反爬机制及影响1. IP 封禁2. 验证码3. 请求头验证4. 动态加载5. 加密与混淆6. 行为分析 应对方法1. 应对 IP 封禁2. 应对验证码3. 应对请求头验证4. 应对动态加载5. 应对加密与混淆6. 应对行为分析 前言 在使用 Python 爬取视频时,会遇到多种反爬…...

STL之序列式容器(Vector/Deque/List)

序列式容器 序列式容器包括:静态数组 array 、动态数组 vector 、双端队列 deque 、单链表 forward_ list 、双链表 list 。这五个容器中,我们需要讲解三个 vector 、 deque 、 list 的使 用,包括:初始化、遍历、尾部插入与删除、…...

小试牛刀-抽奖程序

编写抽奖程序 需求:设计一个抽奖程序,点击抽奖按钮随机抽取一个名字作为中奖者 目标:了解项目结构,简单UI布局,属性方法、事件方法,程序运行及调试 界面原型 ​ 待抽奖: 点击抽奖按钮&#x…...

Vue 3 中 ref 与 reactive 的对比

Vue 3 中 ref 与 reactive 的对比 Vue 3 中 ref 与 reactive 的对比一、定义和基本使用refreactive 二、响应式原理refreactive 三、适用场景refreactive 四、注意事项refreactive Vue 3 中 ref 与 reactive 的对比 在 Vue 3 中,ref 和 reactive 都是用于创建响应式…...

centos-stream-9上安装nvidia驱动和cuda-toolkit

这里写目录标题 驱动安装1. 更新系统2. NVIDIA GPU安装检查系统是否安装了 NVIDIA GPU2.1 首先,使用以下命令更新 DNF 软件包存储库缓存:2.2 安装编译 NVIDIA 内核模块所需的依赖项和构建工具2.3 在 CentOS Stream 9 上添加官方 NVIDIA CUDA 软件包存储库…...

从 MySQL 切换到国产 YashanDB 数据库时,需要在数据库字段和应用连接方面进行适配 ,使用总结

YashanDB | 崖山数据库系统 - 崖山科技官网崖山数据库系统YashanDB是深圳计算科学研究院完全自主研发设计的新型数据库系统,融入原创理论,支持单机/主备、共享集群、分布式等多种部署方式,覆盖OLTP/HTAP/OLAP交易和分析混合负载场景&#xff…...

【学习笔记】头文件中定义函数出现重复定义报错

目录 错误复现原因解决方案inlinestatic 扩展参考 错误复现 现在有一个头文件 duplicate_define.h 和两个源文件 duplicate_define_1.cpp 和 duplicate_define_2.cpp。 两个源文件都引入了头文件 duplicate_define.h,且在各自的函数中调用了定义在头文件中的全局函…...

游戏开发中 C#、Python 和 C++ 的比较

🎬 Verdure陌矣:个人主页 🎉 个人专栏: 《C/C》 | 《转载or娱乐》 🌾 种完麦子往南走, 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持!❤️ 摘要: 那么哪种编程语言最适合游戏开发…...

linux上anaconda安装、卸载、及不同用户共享同个anaconda的操作

这里写目录标题 1、anaconda安装2、所有账号可以访问condastep1: 创建文件step2: 追加以下内容:step3: 赋予执行权限:step4: 生效方式: 3、anaconda3的卸载(1)删除安装文件夹(2)在当前终端会话中…...

利用持久变量绕过长度限制 + unicode特性绕过waf-- xyctf 出题人已疯12 复现

本文章附带TP(Thinking Process)! 黑盒查看网站不具有功能,需要审计代码 # 定义/attack路径的路由 bottle.route(/attack) def attack():# 从请求的查询参数中获取payloadpayload bottle.request.query.get(payload)# 检查payload是否存在,长度是否小于25&#xff…...

大数据技术与Scala

集合高级函数 过滤 通过条件筛选集合元素,返回新集合。 映射 对每个元素应用函数,生成新集集合 扁平化 将嵌套集合展平为单层集合。 扁平化映射 先映射后展平,常用于拆分字符串。 分组 按规则将元素分组为Map结构。 归约 …...

DeepSeek 都开源了哪些技术?

DeepSeek作为中国领先的人工智能企业,通过开源策略推动了全球AI技术的普及与创新。以下是其官方公布的主要开源项目及其技术内容、应用场景和社区反馈的详细分析: 1. FlashMLA 技术描述:专为Hopper架构GPU优化的高效MLA(Multi-Layer Attention)解码内核,针对可变长度序列…...

P8754 [蓝桥杯 2021 省 AB2] 完全平方数

题目描述 思路 一看就知道考数学,直接看题解试图理解(bushi) 完全平方数的质因子的指数一定为偶数。 所以 对 n 进行质因数分解,若质因子指数为偶数,对结果无影响。若质因子指数为奇数,则在 x 中乘以这个质因子,保证指…...

ADGaussian:用于自动驾驶的多模态输入泛化GS方法

25年4月来自香港中文大学和浙大的论文“ADGaussian: Generalizable Gaussian Splatting for Autonomous Driving with Multi-modal Inputs”。 提出 ADGaussian 方法,用于可泛化的街道场景重建。所提出的方法能够从单视图输入实现高质量渲染。与之前主要关注几何细…...

0501路由-react-仿低代码平台项目

文章目录 1 react路由1.1 核心库&#xff1a;React Router安装 1.2 基本路由配置路由入口组件定义路由 1.3 导航方式使用 <Link> 组件编程式导航 1.4 动态路由参数定义参数获取参数 1.5 嵌套路由父路由配置子路由占位符 1.6 重定向与404页面重定向404页面 1.7 路由守卫&a…...

MySQL NULL 值处理

MySQL NULL 值处理 引言 在数据库管理系统中&#xff0c;NULL 值是一个非常重要的概念。在 MySQL 中&#xff0c;NULL 值代表未知、不存在或未定义的值。正确处理 NULL 值对于保证数据的准确性和完整性至关重要。本文将详细介绍 MySQL 中 NULL 值的处理方法&#xff0c;包括 …...