Async、await是什么?跟promise有什么区别?使用的好处是什么

Async/Await 与 Promise 的深度解析

一、基本概念

1. Promise

Promise 是 ES6 引入的异步编程解决方案,表示一个异步操作的最终完成(或失败)及其结果值。

function fetchData() {return new Promise((resolve, reject) => {setTimeout(() => resolve('数据获取成功'), 1000);});
}fetchData().then(data => console.log(data)).catch(error => console.error(error));

2. Async/Await

Async/Await 是 ES2017 (ES8) 引入的语法糖,基于 Promise 的更高层抽象,使异步代码看起来像同步代码。

async function getData() {try {const data = await fetchData();console.log(data);} catch (error) {console.error(error);}
}

二、核心区别

特性PromiseAsync/Await
代码结构链式调用(.then().catch())同步写法(try-catch 块)
可读性嵌套多时较难阅读线性执行,更易理解
调试调试.then()链较困难可以像同步代码一样调试
错误处理必须使用.catch()可以使用try-catch
返回值总是返回Promiseasync函数返回Promise
流程控制需要手动链接多个Promise可以用普通控制结构(for, if等)

三、Async/Await 的优势

1. 代码更简洁直观

// Promise方式
function getUserAndPosts(userId) {return fetchUser(userId).then(user => fetchPosts(user.id)).then(posts => console.log(posts)).catch(error => console.error(error));
}// Async/Await方式
async function getUserAndPosts(userId) {try {const user = await fetchUser(userId);const posts = await fetchPosts(user.id);console.log(posts);} catch (error) {console.error(error);}
}

2. 更自然的错误处

// 传统Promise错误处理可能遗漏
fetchData().then(data => process(data))// 忘记添加catch会导致静默失败// Async/Await强制更安全的写法
async function safeFetch() {try {const data = await fetchData();return process(data);} catch (error) {console.error('处理失败:', error);throw error; // 可选择重新抛出}
}

3. 更简单的流程控制

// 顺序执行多个异步操作
async function sequentialOps() {const result1 = await operation1();const result2 = await operation2(result1);return operation3(result2);
}// 条件执行
async function conditionalOp(shouldFetch) {if (shouldFetch) {return await fetchData();}return cachedData();
}// 循环中的异步操作
async function processItems(items) {for (const item of items) {await processItem(item); // 顺序处理}
}

四、使用注意事项

1. 常见误区

// 错误1:忘记await
async function oops() {const data = fetchData(); // 缺少await,data将是Promise对象console.log(data); // 输出Promise而非结果
}// 错误2:过度顺序化
async function slowOps() {const a = await getA(); // 等待const b = await getB(); // 继续等待(如果无依赖关系应该并行)// 应该改为:// const [a, b] = await Promise.all([getA(), getB()]);
}

2. 性能优化

// 并行执行独立操作
async function parallelOps() {const [user, posts] = await Promise.all([fetchUser(),fetchPosts()]);return { user, posts };
}

3. 顶层Await

ES2022 支持在模块顶层使用 await:

// module.js
const data = await fetchData();
export default data;

五、如何选择

  1. 使用Async/Await当

    • 需要顺序执行多个异步操作

    • 需要更清晰的错误处理

    • 代码可读性是首要考虑

  2. 使用Promise当

    • 需要更精细的控制流(如同时触发多个操作)

    • 需要直接操作Promise(如Promise.race)

    • 在不能使用async/await的环境(如某些旧浏览器)

六、实际应用示例

1. API请求处理

async function fetchUserWithPosts(userId) {try {const user = await api.get(`/users/${userId}`);const posts = await api.get(`/users/${userId}/posts`);return { ...user, posts };} catch (error) {if (error.response?.status === 404) {throw new Error('用户不存在');}throw error;}
}

2. 数据库事务

async function transferFunds(senderId, receiverId, amount) {const connection = await db.getConnection();try {await connection.beginTransaction();await connection.query('UPDATE accounts SET balance = balance - ? WHERE id = ?',[amount, senderId]);await connection.query('UPDATE accounts SET balance = balance + ? WHERE id = ?',[amount, receiverId]);await connection.commit();} catch (error) {await connection.rollback();throw error;} finally {connection.release();}
}

Async/Await 不是替代 Promise 的技术,而是基于 Promise 的更优雅的语法糖。理解两者关系后,可以根据场景灵活选择或混合使用。

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

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

相关文章

MySQL数据库中所有表的空间占用与行数统计

查看某个数据库中所有表的空间与行数统计 SELECT TABLE_NAME AS 表名,TABLE_ROWS AS 行数,ROUND(DATA_LENGTH / 1024 / 1024, 2) AS 数据大小(MB),ROUND(INDEX_LENGTH / 1024 / 1024, 2) AS 索引大小(MB),ROUND((DATA_LENGTH INDEX_LENGTH) / 1024 / 1024, 2) AS 总占用空间(…

el-upload 点击上传按钮前先判断条件满足再弹选择文件框

解决思路: 先写一个上传按钮,点击上传按钮后判断条件是否满足,满足则显示上传组件并使用ref来控制点击事件,隐藏自身。 注:上传成功或者上传失败时或者上传前判断条件添加不满足return将this.isShow true 代码部分…

django ReturnDict 如何修改内容

在Django中,QuerySet 对象通常用于从数据库中检索数据,并且可以被转换为各种格式,例如字典。如果你想修改QuerySet返回的结果(例如,将其转换为dict),你可以在查询执行后进行操作。这里有几种常见…

密室出逃消消乐小游戏微信流量主小程序开源

这个密室出逃消消乐小游戏采用了微信小程序的标准目录结构,包含以下核心功能: 游戏界面:6x6 的网格布局,随机生成不同类型的物品 游戏逻辑:交换相邻物品,消除三个或以上相同类型的物品 计分系统&#xff1a…

SmartMediaKit实战经验总结之高稳定、低延迟、强兼容

在万物互联与数字化加速融合的今天,音视频实时通信技术正成为各行业发展的核心驱动力。从教育到工业、从安防到远程医疗,毫秒级低延迟的音视频交互体验已成为新一代实时系统的“生命线”。而在这个领域,视沃科技旗下的大牛直播SDK&#xff08…

前端性能调优工具与指标

性能指标解析 核心Web指标 核心Web指标(Core Web Vitals)是Google定义的一组关键性能指标&#xff0c;直接影响用户体验和SEO排名&#xff1a; FCP (First Contentful Paint): 首次内容绘制&#xff0c;记录页面首次渲染任何文本、图像、非白色画布或SVG的时间点 优: < 1.…

LeeCode2294划分数组使最大值为K

项目场景&#xff1a; 给你一个整数数组 nums 和一个整数 k 。你可以将 nums 划分成一个或多个 子序列 &#xff0c;使 nums 中的每个元素都 恰好 出现在一个子序列中。 在满足每个子序列中最大值和最小值之间的差值最多为 k 的前提下&#xff0c;返回需要划分的 最少 子序列…

中国医科大借iMeta影响因子跃升至33.2(中科院1区)东风,凭多组学联合生信分析成果登刊

中国医科大借iMeta影响因子跃升至33.2&#xff08;中科院1区&#xff09;东风&#xff0c;凭多组学联合生信分析成果登刊 2025年6月18日&#xff0c;科睿唯安正式发布了2024年期刊的最新影响因子(发送关键词 “2024JIF” 至 “生信学术纵览”&#xff0c;即可下载完整版最新影…

百度垂搜数据管理系统弹性调度优化实践

百度垂直搜索系统将搜索核心能力赋能阿拉丁&#xff08;百度搜索特型结果&#xff09;、垂直领域搜索、应用内搜索等场景&#xff0c;支撑了数百个检索场景、百亿级内容数据的检索。随着接入业务数量和数据量不断增长&#xff0c;系统在海量数据管理与调度上遭遇新的挑战&#…

什么是Nacos?

Nacos&#xff08;Naming and Configuration Service&#xff09;是一个由阿里巴巴开源的动态服务发现、配置管理和服务管理平台&#xff0c;专为云原生应用设计。它是构建微服务架构的核心基础设施之一&#xff0c;主要解决分布式系统中的服务注册发现和动态配置管理两大核心问…

golang excel导出时需要显示刷新

"github.com/xuri/excelize/v2"包导出excel文件时在调用WriteTo函数前需要显式关闭流写入器 if err : sw.Flush(); err ! nil { return nil, err } &#xff0c;否则会造成excel文件使用excel打开时出现问题&#xff0c;但是用wps打开文件就没有此问题 详细代码&…

Make RL Great Again:大语言模型时代的强化学习推理丨记深度推理模型论坛

进入2025年&#xff0c;大模型依赖Scaling Law提升性能的方式正面临边际递减。一方面算力成本居高不下&#xff0c;另一方面训练效率与推理质量难以兼顾。在这种背景下&#xff0c;模型正悄然从“模仿机器”转向“思考引擎”。 6月7日&#xff0c;以“推理”为核心的智源大会深…

MATLAB R2025a安装教程

软件介绍 MATLAB 是由MathWorks公司开发的高级数值计算软件&#xff0c;在工程计算、数据分析和算法开发领域应用广泛&#xff0c;以下是其相关介绍&#xff1a; 功能特点 ・矩阵运算与可视化&#xff1a;提供强大的矩阵处理能力&#xff0c;内置丰富的绘图函数&#xff0c;可快…

Flink CDC MySQL 表字段定义为 decimal 输出乱码问题优雅解决方式

Flink CDC MySQL 表字段定义为 decimal 输出乱码问题解析 代码运行环境 Flink 1.15 + FlinkCDC 2.4.0 + jdk1.8 +springboot 2.31、原因分析 Flink CDC 底层使用 Debezium 连接器来捕获 MySQL 的数据变更。当 MySQL 表中的字段类型为 decimal 时,Debezium 默认会将 decimal…

spring-webmvc @ResponseStatus 典型用法

典型用法 为某个接口指定固定的 HTTP 状态码&#xff08;如创建成功返回 201&#xff09; 当该方法执行成功时&#xff0c;HTTP 响应状态码会是 201 Created。 适用于不需要动态控制状态码的场景。 PostMapping("/users") ResponseStatus(HttpStatus.CREATED) pub…

鸿蒙Next仓颉语言开发实战教程:设置页面

仓颉语言商城应用的页面开发教程接近尾声了&#xff0c;今天要分享的是设置页面&#xff1a; 导航栏还是老样式&#xff0c;介绍过很多次了&#xff0c;今天不再赘述。这个页面的内容主要还是介绍List容器的使用。 可以看出列表内容分为三组&#xff0c;所以我们要用到ListIte…

Redis 第三讲 --- 指令篇 通用命令(一)

前言&#xff1a; 在《Redis 第二讲》中&#xff0c;我们完成了 Redis 的安装与环境配置&#xff0c;为实际操作奠定了基础。本讲将正式进入 Redis 的核心领域——指令操作。我们将从最基础的键值操作开始&#xff0c;逐步掌握数据读写、键管理及生产环境注意事项&#xff0c;…

数字媒体专业课程介绍以及就业方向

专业课程体系融合艺术创作与技术实践,旨在培养兼具美学素养和产业应用能力的复合型人才。以下是核心课程模块及代表性课程,涵盖从基础到高阶的全流程训练: 🎨 一、核心课程体系 艺术基础课程 绘画训练:素描、速写、色彩理论、构成艺术,培养造型能力与色彩运用2610。 动…

Spring-创建第一个SpringBoot项目

目录 一.使用IDEA创建 1.专业版 2.社区版 二.使用网页创建项目 三.项目目录介绍 一.使用IDEA创建 1.专业版 修改Server URL为https://start.aliyun.com 2.社区版 这里需要注意对应的IDEA版本&#xff0c;版本不对导入无法使用。 不需要解压&#xff0…

【数据分析三:Data Storage】数据存储

数据真是越来越多啊 正文开始 一、数据 结构化数据 可以使用关系型数据库表示和存储的数据&#xff0c;拥有固定结构 半结构化数据 弱结构化&#xff0c;虽然不符合关系型数据模型的要求&#xff0c;但是含有相关的标记(自描述结构)&#xff0c;分割实体及其属性 。如&#xf…