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

写给Pythoner的前端进阶指南(四):异步编程 - 原生支持的 async/await

在开发中,异步编程是处理并发任务的重要方式。无论是请求数据、读取文件还是执行网络操作,异步编程能够有效提升程序的性能和响应速度。Python 和 JavaScript 都支持异步编程,但它们的实现方式有所不同。在这篇文章中,我们将深入探讨 JavaScript 中的异步编程,特别是如何通过回调函数、Promise 以及 async/await 来处理异步任务。对于熟悉 Python 的开发者来说,理解 JavaScript 中的异步编程模式,将有助于你在不同语言之间的过渡。

一、回调函数

1.1 什么是回调函数?

回调函数是指作为参数传递给另一个函数,并在外部函数执行完成后被调用的函数。在 JavaScript 中,回调函数通常用于处理异步操作,比如网络请求、文件读取等。回调函数常见于处理异步任务,然而,当存在多个异步操作时,回调函数容易变得难以维护,这种现象被称为 回调地狱

回调函数的例子:
// 传统回调函数示例
function fetchData(callback) {setTimeout(() => {console.log("Data fetched");callback("Fetched data");}, 1000);
}fetchData(function(data) {console.log("Received:", data);
});

1.2 回调地狱(Callback Hell)

当有多个嵌套的异步操作时,代码会变得复杂且难以维护。我们称之为“回调地狱”或“回调金字塔”。

// 回调地狱示例
fetchData(function(data1) {processData(data1, function(data2) {saveData(data2, function(response) {console.log("Data saved:", response);});});
});

回调地狱的问题主要在于代码的嵌套层次过多,导致代码可读性差,错误排查也非常困难。

二、Promise

2.1 什么是 Promise?

Promise 是 JavaScript 为了简化异步代码而引入的一种新的机制。它表示一个异步操作的最终完成(或失败)及其结果值。Promise 可以链式调用,使得异步代码更加清晰易懂。一个 Promise 有三种状态:pending(等待中)、fulfilled(已完成)、rejected(已拒绝)。

使用 Promise 进行异步操作:
// 返回一个 Promise 示例
function fetchData() {return new Promise((resolve, reject) => {setTimeout(() => {const success = true;if (success) {resolve("Data fetched");} else {reject("Error fetching data");}}, 1000);});
}fetchData().then(result => console.log(result))  // 输出: Data fetched.catch(error => console.log(error));  // 处理错误

2.2 Promise 的链式调用

通过链式调用,Promise 可以串联多个异步操作,从而避免了回调地狱问题。每个 .then() 都返回一个新的 Promise,因此可以进行进一步的链式调用。

// 链式调用示例
fetchData().then(result => {console.log(result);return processData(result);  // 返回一个新的 Promise}).then(processedData => {console.log("Processed data:", processedData);return saveData(processedData);}).then(savedData => {console.log("Saved data:", savedData);}).catch(error => {console.log("Error:", error);});

通过链式调用,代码变得更加简洁,并且错误处理可以集中在 .catch() 中,提升了代码的可维护性。

三、async/await

3.1 async/await 概述

async/await 是 JavaScript ES2017 引入的异步编程新语法,它基于 Promise,但提供了更简洁的语法和更好的可读性。async 用于定义一个返回 Promise 的函数,而 await 用于等待一个 Promise 完成,并返回其结果。通过 async/await,异步代码看起来像是同步代码,使得程序更易于理解和维护。

使用 async/await 处理异步操作:
// async/await 示例
async function fetchData() {return new Promise(resolve => {setTimeout(() => {resolve("Data fetched");}, 1000);});
}async function main() {try {const result = await fetchData();  // 等待异步操作完成console.log(result);  // 输出: Data fetched} catch (error) {console.log("Error:", error);}
}main();

3.2 错误处理(try/catch)

async/await 提供了类似同步代码的错误处理机制,使用 try/catch 来捕获异常。如果一个 await 表达式的 Promise 被拒绝(rejected),错误会被抛到 catch 块中。

async function fetchData() {throw new Error("Data fetch failed");
}async function main() {try {const result = await fetchData();console.log(result);} catch (error) {console.log("Error:", error.message);  // 输出: Error: Data fetch failed}
}main();

3.3 async/await 与 Promise 的比较

  • async/await 语法更接近同步代码,避免了大量的 .then().catch() 链式调用,提升了代码可读性。
  • async/await 仍然是基于 Promise 的,因此它可以与 Promise 互换使用。
// async/await 与 Promise 的对比
async function fetchData() {return new Promise(resolve => {setTimeout(() => resolve("Data fetched"), 1000);});
}// 使用 Promise
fetchData().then(result => console.log(result));// 使用 async/await
async function main() {const result = await fetchData();console.log(result);
}
main();

四、与 Python 的异步编程对比

Python 和 JavaScript 都提供了异步编程的机制,但它们的实现方式有所不同。Python 使用 asyncio 库,而 JavaScript 使用 async/await

4.1 Python 中的异步编程(asyncio

在 Python 中,异步编程通过 asyncio 库实现,asyncio 提供了 asyncawait 关键字,语法上与 JavaScript 类似。

Python 中的 asyncio 示例:
import asyncioasync def fetch_data():await asyncio.sleep(1)return "Data fetched"async def main():result = await fetch_data()print(result)# 运行异步代码
asyncio.run(main())

4.2 JavaScript 中的 async/await

虽然 Python 和 JavaScript 的异步编程语法相似,但它们的实现背景有所不同:

  • Python (asyncio): Python 使用 asyncio 库来管理异步任务,通常适用于单线程并发操作。
  • JavaScript (async/await): JavaScript 原生支持异步操作,通常用于处理 I/O 密集型任务,运行时环境(如浏览器或 Node.js)负责处理事件循环。

4.3 异步模型对比

  • Python 的 asyncio 是基于事件循环的模型,它使用一个协程调度器来管理并发任务,适用于高并发和 I/O 密集型操作。
  • JavaScript 的 async/await 语法与事件循环模型密切集成,通常用于浏览器端或 Node.js 中进行并发处理。

结语

通过本篇文章,你应该对 JavaScript 中的异步编程有了更深入的理解。从回调函数到 Promise,再到 async/await,逐步简化了异步编程的复杂性。对于 Python 开发者来说,JavaScript 中的异步编程语法与 Python 的 asyncio 非常相似,理解了两者的异同,可以帮助你更快地在不同语言之间切换。

异步编程是现代 Web 开发中不可或缺的一部分,掌握它能够使你处理更多并发任务,提高应用的性能和响应速度。如果你有任何问题,欢迎在评论区讨论或分享你的经验!

相关文章:

写给Pythoner的前端进阶指南(四):异步编程 - 原生支持的 async/await

在开发中,异步编程是处理并发任务的重要方式。无论是请求数据、读取文件还是执行网络操作,异步编程能够有效提升程序的性能和响应速度。Python 和 JavaScript 都支持异步编程,但它们的实现方式有所不同。在这篇文章中,我们将深入探…...

项目搭建+姓名唯一性校验

一 : 添加时对姓名进行唯一性校验 ① : 给姓名绑定一个改变事件 ② : 取值 ③ : 组装对象 ④ : ajax (Controller定义对姓名唯一性校验的方法) 在成功回调函数里 判断姓名是否添加过(0>已添加 1>未添加) 未添加过,添加成功后,(清空) /*** 对姓名进行唯一性校验*/$("…...

MacOS下PostIn安装配置指南

PostIn是一款开源免费的接口管理工具, 下面介绍私有部署版本的MacOS下安装与配置。私有部署版本更适合有严格数据安全要求的企业,实现对数据和系统的完全控制。   1、MacOS服务端安装 Mac安装包下载地址:下载Mac安…...

时光回响,中原之声 ——漓岛⾳乐节x SONICE

音乐像呼吸一样在大地起伏,中原的回响透过时空,从遥远的内陆弥漫扩散至温暖的南方,年轻的呼唤似一阵快雨淋落在辽阔的海面,波澜游弋,终掀浪涛。来自中原的独立音乐厂牌SONICE将与澄迈漓岛音乐节联合呈现乘风舞台&#…...

获取apk信息(包名,版本等) aapt dump badging (apk文件路径)

1.找到sdk路径下aapt文件: Android\Sdk\build-tools\29.0.0 (29.0.0是构建版本,可以是其他版本如27.0.3) 2.window dos窗口cd 到这个路径下:Android\Sdk\build-tools\29.0.0 ,也可以配置到 环境变量 3.执行 aapt dump badging (apk文件路径…...

C++ 23版的最新特性

C 23 是 C 编程语言的最新标准版本,于 2023 年正式发布,带来了诸多新特性与改进,以下是一些主要内容: 1.语言特性 1.显式对象参数(Deducing this):显式对象参数(Deducing this&…...

【微信小程序开发 - 3】:项目组成介绍

文章目录 项目组成介绍项目的基本组成结构小程序页面的组成部分JSON配置文件的作用app.json文件project.config.json文件sitemap.json文件页面的 .json 配置文件新建小程序页面修改项目首页 XWML模板XWML 和 HTML 的区别 WXSS样式WXSS 和 CSS 的区别 .js文件 项目组成介绍 项目…...

分布式超低耦合,事件驱动架构(EDA)深度解析

目录 引言什么是事件驱动架构(EDA)事件驱动架构的基本原理事件驱动架构的特点与优势事件驱动架构与分布式系统事件驱动架构的关键组件事件驱动架构的实施步骤常见的事件驱动架构模式事件驱动架构在分布式系统中的应用场景挑战与解决方案总结 引言 在当…...

深入理解 Linux wc 命令

文章目录 深入理解 Linux wc 命令1. 基本功能2. 常用选项3. 示例3.1 统计文件的行、单词和字符数3.2 仅统计行数3.3 统计多个文件的总和3.4 使用管道统计命令输出的行数 4. 实用案例4.1 日志分析4.2 快速统计代码行数4.3 统计单词频率 5. 注意事项6. 总结 深入理解 Linux wc 命…...

轻松拿捏Spring

目录 Spring基础 什么是Spring框架 Spring 包含的模块有哪些? Core Container AOP Data Access/Integration Spring Web Messaging Spring Test Spring,Spring MVC,Spring Boot 之间什么关系? Spring基础 什么是Spring框架 Spring 是一款开源的轻量级 Java 开发框…...

使用 `du` 命令可以查看根目录下每个子目录占用的磁盘空间大小

使用 du 命令可以查看根目录下每个子目录占用的磁盘空间大小。 查看根目录下子目录大小的命令 sudo du -sh /*解释: du:显示文件和目录的磁盘使用情况。-s:只显示每个目录的总大小(不递归显示子目录)。-h&#xff1…...

Python练习之列表的使用

(搭配主页知识点) 【练习要求】 针对知识点列表定义、追加、列表元素读取、查找安排的本实例。要求实现:有一个列表,内容是:[21,25,21,23,22,20],记录的是一批学生的年龄请通过列表的功能(方法),对其进行…...

深入理解 HTTP HEAD 请求:节省带宽、提高效率的秘密武器

序言: 在HTTP协议中,HEAD请求是一种非常实用且被忽略的请求方法。与GET请求相似,HEAD请求同样从服务器获取资源,但与GET请求的最大不同之处在与,HEAD请求 仅返回响应的头部信息,不包含内容提。这使得HEAD请…...

电商数据流通的未来:API接口的智能化与自动化趋势

在数字化时代,电子商务行业正在以前所未有的速度发展,而API(应用程序编程接口)接口作为电商领域的重要组成部分,其应用和发展趋势也日益受到关注。API接口作为电商系统与外部服务或平台交互的桥梁,对电商数…...

[python]使用flask-caching缓存数据

简介 Flask-Caching 是 Flask 的一个扩展,为任何 Flask 应用程序添加了对各种后端的缓存支持。它基于 cachelib 运行,并通过统一的 API 支持 werkzeug 的所有原始缓存后端。开发者还可以通过继承 flask_caching.backends.base.BaseCache 类来开发自己的…...

13.罗意文面试

1、工程化与架构设计(考察项目管理和架构能力) 1.1 你负责的可视化编排项目中,如何设计组件的数据结构来支持"拖拉拽"功能?如何处理组件间的联动关系? // 组件数据结构示例 {components: [{id: comp1,type…...

有监督学习 vs 无监督学习:机器学习的两大支柱

有监督学习 vs 无监督学习:机器学习的两大支柱 有监督学习 vs 无监督学习:机器学习的两大支柱一、有无“老师”来指导二、解决的问题类型不同三、模型的输出不同 有监督学习 vs 无监督学习:机器学习的两大支柱 在机器学习的奇妙世界里&#…...

创建第一个QML项目

文章目录 使用 Qt Creator 创建 Qt Quick 项目详解为什么选择 Qt Creator?1. 打开 Qt Creator2. 选择项目模板3. 设置项目名称与路径4. 定义项目细节5. 配置构建套件6. 检查项目配置7. 编译并运行项目后续操作修改界面添加功能 总结 使用 Qt Creator 创建 Qt Quick …...

【k8s集群应用】K8S二进制安装大致步骤(简略版)

文章目录 K8S二进制安装部署etcd测试etcd集群(可选)恢复etcd数据库 部署master组件部署node组件K8S kubeadm安装关键命令更新kubeadm安装的K8S证书有效期方法一方法二查看证书有效期 K8S二进制安装 部署etcd 使用cfssl工具签发证书和私钥下载解压etcd软…...

cudnn版本gpu架构

nvcc --help 可以看 --gpu-architecture 写到的支持的架构 NVIDIA 的 GPU 架构是按代次发布的,以下是这些架构的对应说明: NVIDIA Hopper: 这是 NVIDIA 于 2022 年推出的架构之一,面向高性能计算(HPC)和人工智能&…...

智能体实战(需求分析助手)一、需求概述及迭代规划

需求分析助手开发迭代规划 功能概述 需求分析助手是一款基于大模型的智能系统,旨在帮助用户高效完成需求获取、需求分析、需求文档编写及需求验证的全流程工作。通过对用户输入的智能处理和分析,需求分析助手能够简化需求管理流程,并根据不同业务场景提供定制化支持。 核心…...

二叉搜索树Ⅲ【东北大学oj数据结构8-3】C++

二叉搜索树 III B:在二叉搜索树II中加入delete指令,创建程序对二叉搜索树T执行如下指令。 插入 k:将key k 插入到 T 中。 find k:报告T中是否存在key k。 delete k:删除key为 k 的节点。 打印:使用中序树遍…...

基于ceres优化的3d激光雷达开源算法

以下是一些基于CERES优化的开源激光雷达SLAM或相关算法: (1) LOAM (Lidar Odometry And Mapping) 简介: LOAM是一种经典的激光雷达里程计和建图算法,它通过提取特征点(角点和平面点),利用ICP(Iterative Cl…...

2023.9 Explainability for Large Language Models: A Survey

问题 可解释性问题:大语言模型(LLMs)内部机制不透明,难以理解其决策过程,如在自然语言处理任务中,不清楚模型如何根据输入生成特定的预测结果。模型评估问题:缺乏有效的评估指标和方法来衡量解…...

集成方案 | Docusign + 金蝶云,实现合同签署流程自动化!

本文将详细介绍 Docusign 与金蝶云的集成步骤及其效果,并通过实际应用场景来展示 Docusign 的强大集成能力,以证明 Docusign 集成功能的高效性和实用性。 在当今商业环境中,流程的无缝整合与数据的实时性对于企业的成功至关重要。金蝶云&…...

[LeetCode-Python版] 定长滑动窗口3——1461. 检查一个字符串是否包含所有长度为 K 的二进制子串

题目 给你一个二进制字符串 s 和一个整数 k 。如果所有长度为 k 的二进制字符串都是 s 的子串,请返回 true ,否则请返回 false 。 示例 1: 输入:s “00110110”, k 2 输出:true 解释:长度为 2 的二进制…...

简单工厂模式和策略模式的异同

文章目录 简单工厂模式和策略模式的异同相同点:不同点:目的:结构: C 代码示例简单工厂模式示例(以创建图形对象为例)策略模式示例(以计算价格折扣策略为例)UML区别 简单工厂模式和策…...

Docker容器五种网络驱动模式详解

Docker 网络用于在容器之间以及容器与外部网络之间提供通信功能。它允许容器在隔离的网络环境中运行,同时也能根据需要与其他容器或外部网络进行交互。通过使用网络驱动,Docker 可以创建不同类型的网络,以满足各种应用场景的需求。 传统上&am…...

从客户跟进到库存管理:看板工具赋能新能源汽车销售

在新能源汽车市场日益扩张的今天,门店销售管理变得更加复杂和重要。从跟踪客户线索到优化订单流程,再到团队协作,效率低下常常成为许多门店的“隐形成本”。如果你曾为销售流程不畅、客户管理混乱而苦恼,那么一种简单直观的工具—…...

汽车IVI中控开发入门及进阶(41):视频播放器MPlayer

版本: MPlayer 1.5 2022年已发布。 MPlayer 1.5与最新FFmpeg版本(5.0)和当前FFmpeg开发版本(FFmpeg master)兼容。tarball已经包含一个FFmpeg快照,因此不需要单独获取它。如果想遵循MPlayer和FFmpeg的最新改进,强烈建议你使用开发版本。 MPlayer - The Movie Playerht…...

Odoo:免费开源ERP的AI技术赋能出海企业电子商务应用介绍

概述 伴随电子商务的持续演进,客户对于便利性、速度以及个性化服务的期许急剧攀升。企业务必要探寻创新之途径,以强化自身运营,并优化购物体验。达成此目标的最为行之有效的方式之一,便是将 AI 呼叫助手融入您的电子商务平台。我们…...

看板工具助力餐饮与酒店行业实现数字化转型,提升管理与运营效率

在餐饮与酒店行业,服务质量和客户体验是衡量企业成功的关键因素。随着客户需求的不断多样化以及市场竞争的加剧,传统的管理模式逐渐难以满足高效运营的需求。尤其在高峰期,如何优化内部流程、提高服务效率和响应速度,成为了许多餐…...

网络安全(3)_安全套接字层SSL

4. 安全套接字层 4.1 安全套接字层(SSL)和传输层安全(TLS) (1)SSL/TLS提供的安全服务 ①SSL服务器鉴别,允许用户证实服务器的身份。支持SSL的客户端通过验证来自服务器的证书,来鉴别…...

国标GB28181网页直播平台EasyGBS:网络摄像机中的音频及音频编码技术解析

在网络摄像机领域,音频质量及其编码方式对于视频监控系统的整体性能至关重要。音频作为视频监控系统的重要组成部分,不仅能够提供现场的声音信息,增强监控的实时性和准确性,还能在事件发生后为调查提供宝贵的语音证据。 一、网络摄…...

为何VisualRules更适合技术人员使用

什么是规则引擎 规则引擎是一种软件组件,它允许将业务规则从应用程序的核心代码中分离出来,以一种更加灵活、易于管理和维护的方式来定义、存储和执行这些规则。简单来说,它就像是一个专门处理规则的 “大脑”,可以根据预先设定的…...

PyTorch 2.0 以下版本中设置默认使用 GPU 的方法

PyTorch 2.0 以下版本中设置默认使用 GPU 的方法 在 PyTorch 2.0以下版本中,默认情况下仍然是使用 CPU 进行计算,除非明确指定使用 GPU。在 PyTorch 2.0 以下版本中,虽然没有 torch.set_default_device 的便捷方法,但可以通过显式…...

Redis篇-19--运维篇1-主从复制(主从复制,读写分离,配置实现,实战案例)

1、概述 Redis的主从复制(Master-Slave Replication)是一种数据冗余机制,它允许将一台Redis服务器的数据复制到其他Redis服务器。在主从复制中,有一台主服务器(Master)和一个或多个从服务器(Sl…...

springboot449教学资源共享平台(论文+源码)_kaic

摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统教学资源共享平台信息管理难度大,容错率低&am…...

Unbuntu下怎么生成SSL自签证书?

环境: WSL2 Unbuntu 22.04 问题描述: Unbuntu下怎么生成SSL自签证书? 解决方案: 生成自签名SSL证书可以使用OpenSSL工具,这是一个广泛使用的命令行工具,用于创建和管理SSL/TLS证书。以下是生成自签名…...

Ubuntu18.04——换源

一、前提说明 系统自带的源往往下载很慢,通过换源操作后,往往下载/更新 速度大幅提升 每种版本对应的不一样,例如Ubuntu18.04和Ubuntu20.04的有差异,所以换源需要根据不同版本对应的命令 二、操作步骤 0.备份原先的 /etc/apt/sou…...

crictl和ctr与docker的命令的对比

crictl是遵循CRI接口规范的一个命令行工具,通常用它来检查和管理kubelet节点上的容器运行时和镜像 ctr是containerd的一个客户端工具, 接下来就是crictl的的常见命令,其中能完全替代docker命令的参照下列表格 操作crictldocker查看运行容器…...

Java 技术面试常见问题解析

1.说说Mybatis的缓存机制: MyBatis 是一个优秀的持久层框架,它简化了企业应用开发中数据库操作的代码。MyBatis 提供了一级缓存和二级缓存机制来优化对数据库的访问。 一级缓存 (SqlSession级别的缓存) 一级缓存是 MyBatis 中默认开启且无法关闭的缓存机制。它存…...

数据结构,链表的简单使用

任意位置删除&#xff1a; void Any_Del(LinkListPtr h,int a)//任意删 {if(NULLh||a>h->len){printf("删除失败");}LinkListPtr ph;for(int i0;i<a-1;i){pp->next;}LinkListPtr p2p;p2p2->next;p->nextp->next->next;free(p2);p2NULL;h-&g…...

go引用包生成不了vendor的问题

比如我要引入github.com/jinzhu/gorm这个包. 1. 首先获取包 go get github.com/jinzhu/gorm 这时go.mod文件中也有这个包依赖信息了. 2. 然后构建vendor go mod vendor 结果发现vendor目录下没有生成对应的包, 而且modules.txt也注释掉这个包了. 原因是没有其进行引用, go…...

C语言——实现求出最大值

问题描述&#xff1a;利用C语言自定义函数求出一维数组里边最大的数字 //利用函数找最大数#include<stdio.h>int search(int s[9]) //查找函数 {int i , max s[0] , max_xia 0;for(i0;i<9;i){if(s[i] > max){max_xia i;max s[max_xia];}}return max; } in…...

【CSS in Depth 2 精译_081】 13.1:CSS 渐变效果(下)——CSS 径向渐变(13.1.3)+ CSS 锥形渐变(13.1.4)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第四部分 视觉增强技术 ✔️【第 13 章 渐变、阴影与混合模式】 ✔️ 13.1 渐变 ✔️ 13.1.1 使用多个颜色节点&#xff08;上&#xff09;13.1.2 颜色插值方法&#xff08;中&#xff09;13.1.3 径…...

【SH】Ubuntu Server 24搭建Web服务器访问Python程序研发笔记

文章目录 说个问题写个方案一、安装Ubuntu Server二、安装Web服务器采用Nginx服务器 三、安装Python及依赖创建项目虚拟环境 四、安装Python Web框架采用Flask框架创建和运行Flask应用&#xff08;以后的重点&#xff09; 五、安装WSGI服务器采用Gunicorn 六、配置Nginx七、验证…...

创建项目以及本地仓库和远程仓库并上传项目

创建项目以及本地仓库和远程仓库并上传项目 其详细流程如下&#xff1a; 1、本地创建项目 2、创建本地仓库&#xff08;若使用idea在创建项目时选择了创建.git本地仓库&#xff0c;则此步骤省略&#xff09; 进入到你需要上传的项目的目录下&#xff0c;右键找到Git Bah He…...

代码开发相关操作

使用Vue项目管理器创建项目&#xff1a;&#xff08;vue脚手架安装一次就可以全局使用&#xff09; windowR打开命令窗口&#xff0c;输入vue ui&#xff0c;进入GUI页面&#xff0c;点击创建-> 设置项目名称&#xff0c;在初始化git下面输入&#xff1a;init project&…...

ElasticSearch系列:利用runtime field实现日期字符串实现日期范围查询

在Elasticsearch中&#xff0c;如果你有一个时间字符串字段&#xff0c;并且你希望在查询时将其转换为date类型以便进行日期范围查询或其他日期相关的操作&#xff0c;你可以使用runtime_fields来实现这一转换。不过&#xff0c;与转换为UNIX时间戳不同&#xff0c;Elasticsear…...