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

【11】ES6:async/await

一、概念

async/await 是 ES2017(ES8)的新特性,它是一种基于 Promise 实现的异步编程方式。async/await 也是一种语法糖。

1、async/await 实现了用同步方式来写异步代码(promise是链式调用形式写异步代码)

2、async 是“异步” 的简写,用来声明一个 function 是异步的

3、await 是 async wait 的简写,用于等待一个异步方法执行完成

4、await 只能出现在 async 函数中

二、async 函数

1、基本使用

在函数声明前添加 async 关键字,表示该函数是异步的。

async 函数的返回值是一个 Promise 对象。 async 函数返回的值可以通过 then() 方法回调函数的参数或者 await 表达式获取。

async 函数内部使用 return 语句返回的值会被自动封装成 Promise 对象,并且该对象的状态会根据 return 语句返回的值类型自动变为 resolved 或 rejected。

async function foo() {return 'Hello World!'
}foo().then(value => console.log(value))
// 'Hello World!'
async function bar() {throw new Error('Something went wrong!')
}bar().catch(error => console.error(error)) 
// 'Error: Something went wrong!'

如果 async 函数中没有 return 语句,则该函数返回一个 undefined 值的 Promise 对象。

async function foo() {const result = await Promise.resolve('Hello World!')console.log('Hello World!')// 等同于 return Promise.resolve(undefined)
}foo().then(value => console.log(value)) 
// 'Hello World!'
// undefined

拓展知识:
如果在async 函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。
Promise.resolve(x) 可以看作是 new Promise(resolve => resolve(x)) 的简写,可以用于快速封装字面量对象或其他对象,将其封装成 Promise 实例。

暂停和恢复执行: 在async 函数内部,可以使用 await 关键字来等待一个 Promise 对象的状态改变。当遇到 await 时,函数会暂停执行,并等待 Promise 对象的状态变为 resolved 或 rejected,然后恢复执行。

async function foo() {console.log('开始执行')await new Promise(resolve => setTimeout(resolve, 2000)) // 等待2秒钟console.log('2秒钟后恢复执行')return '完成'
}console.log('调用函数')foo().then(value => {console.log('异步函数返回值:', value)
})console.log('继续执行')// 调用函数
// 开始执行
// 继续执行
// 2秒钟后恢复执行
// 异步函数返回值: 完成

在上面的示例中,我们定义了一个 foo 的 async 函数。首先在主线程中调用 foo 函数,然后输出开始执行和继续执行。接下来,我们使用 await 关键字等待一个 2 秒钟后 resolved 的 Promise 对象。在等待期间,函数会暂停执行,并且主线程可以继续执行其他代码。当 2 秒钟过去后,Promise 对象的状态变为 resolved,await 表达式会返回 resolved 的值(在此例中为 undefined),并且函数恢复执行,输出 2 秒钟后恢复执行。最后,foo 函数返回一个 resolved 状态的 Promise 对象,该对象的值为’完成’。在 then 方法的回调函数中,我们打印出异步函数的返回值完成。

2、async 函数的多种使用形式

// 函数声明
async function foo() {}// 函数表达式
const foo = async function () {}// 对象的方法
let obj = { async foo() {} }
obj.foo().then(...)// Class 的方法
class Storage {constructor() {this.cachePromise = caches.open('avatars')}async getAvatar(name) {const cache = await this.cachePromisereturn cache.match(`/avatars/${name}.jpg`)}
}const storage = new Storage()
storage.getAvatar('jake').then()// 箭头函数
const foo = async () => {}

三、await 命令

await 只能在 async 函数内部使用,它会暂停 async 函数的执行,等待 Promise 对象的状态改变,然后再继续执行 async 函数。

正常情况下,await 命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。(promise 对象、async 函数、普通数据)

async function f() {// 等同于 return 123return await 123
}f().then(v => console.log(v))
// 123

错误处理 与 try…catch 使用

await 命令后面的 Promise 对象如果变为 reject 状态,则 reject 的参数会被 catch 方法的回调函数接收到。

async function f() {await Promise.reject('出错了')
}f()
.then(v => console.log(v))
.catch(e => console.log(e))
// 出错了

任何一个 await 语句后面的 Promise 对象变为 reject 状态,那么整个 async 函数都会中断执行。

async function f() {await Promise.reject('出错了')await Promise.resolve('hello world') // 不会执行
}

有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个 await 放在 try…catch 结构里面,这样不管这个异步操作是否成功,第二个 await 都会执行。

async function f() {try {await Promise.reject('出错了')} catch(e) {}return await Promise.resolve('hello world')
}f().then(v => console.log(v))
// hello world

另一种方法是 await 后面的 Promise 对象再跟一个 catch 方法,处理前面可能出现的错误。(了解)

async function f() {await Promise.reject('出错了').catch(e => console.log(e))return await Promise.resolve('hello world')
}f().then(v => console.log(v))
// 出错了
// hello world

如果有多个 await 命令,可以统一放在 try…catch 结构中。

async function main() {try {const val1 = await firstStep()const val2 = await secondStep(val1)const val3 = await thirdStep(val1, val2)console.log('Final: ', val3)} catch (err) {console.error(err)}
}

四、async/await 与 promise 比较

async/await 是一种更加直观、简洁且易读的异步处理方式,适合处理复杂的异步操作流程和错误处理。而 promise 则更加底层,可以用于更细粒度的异步控制和组合操作。在实际开发中,可以根据具体的需求和场景选择合适的异步处理方式。

语法差异

promise 是基于回调函数的异步处理方式,使用 then 和 catch 方法来处理异步操作的结果和错误。

async/await 是一种基于生成器函数(Generator)和 promise 的语法糖,通过在函数前面加上 async 关键字,将函数转换为返回 promise 对象的异步函数,并使用 await 关键字等待异步操作的结果。

可读性

promise 以链式调用的形式书写异步代码。

async/await 以同步形式书写异步代码。更加直观和易读,代码结构更加清晰。

错误处理

promise 中,通常使用 catch 方法来捕获和处理错误。

async/await 中,通常使用 try…catch 语句来捕获和处理错误。

异步操作的顺序

promise 中,如果有多个异步操作需要按照特定的顺序执行,我们需要通过嵌套的 then 方法或使用 Promise.all、Promise.race 等组合方法来实现。

async/await 中,可以使用同步的代码风格来编写异步操作的顺序,使代码更加简洁和可读。

错误堆栈

promise 中,当发生错误时,错误信息中会包含详细的堆栈信息,可以追踪到错误发生的位置。

async/await 中,由于使用了 try…catch 语句捕获错误,堆栈信息可能会被截断,不够详细。

function fetchUser(userId) {return new Promise((resolve, reject) => {setTimeout(() => {if (userId === 1) {resolve({ id: userId, name: 'Alice' })} else {reject(new Error('User not found'))}}, 1000)})
}// 使用 Promise 实现异步操作
fetchUser(1).then(user => console.log(user)).catch(error => console.error(error))// 使用 async/await 实现异步操作
async function getUser(userId) {try {const user = await fetchUser(userId)console.log(user)} catch (error) {console.error(error)}
}
getUser(1)

相关文章:

【11】ES6:async/await

一、概念 async/await 是 ES2017(ES8)的新特性,它是一种基于 Promise 实现的异步编程方式。async/await 也是一种语法糖。 1、async/await 实现了用同步方式来写异步代码(promise是链式调用形式写异步代码) 2、asyn…...

深入理解Java集合框架

导语: Java集合框架是Java提供的一组用于管理对象的类和接口,它是Java编程中非常重要的一部分。Java集合框架通过提供诸如List、Set、Map等数据结构,为程序员提供了一种方便、高效的管理对象的方式。本文将深入理解Java集合框架,包…...

极智嘉加快出海发展步伐,可靠产品方案获客户认可

2023年,国内本土企业加快出海征程,不少企业在出海发展中表现出了优越的集团实力与创新的产品优势,有力彰显了我国先进的科技研发实力。作为全球仓储机器人引领者,极智嘉(Geek)也在不断加快出海发展步伐&…...

运动目标检测方法的概述

目录 ① 光流法 ② 帧差法 ③ 背景差分法 ④ 混合高斯模型法 ⑤ 总结 运动目标检测技术的应用十分的广泛,尤其是在智能视频监控领域。运动目标检测为后续的图像处理等操作提供了基础,在某种程度上,决定了整个系统的性能。运动目标检测&a…...

【Qt-Edit】

Qt编程指南 ■ QTextEdit■ QLineEdit■ QLineEdit 设置正则表达式■ QPlainTextEdit■ QKeySequenceEdit■ QList<QLineEdit *> edits■■■ QTextEdit /* 实例和对象,设置位置和显示大小 */ textEdit = new QTextEdit(this)...

vue data变量不能以“_”开头,否则会产生很多怪异问题

1、 比如给子组件赋值&#xff0c;子组件无法得到这个值&#xff08;也不是一直无法得到&#xff0c;设置后this.$forceUpdate() 居然可以得到&#xff09;&#xff0c; 更无法watch到 <zizujian :config"_config1"> </zizujian>this._config1 { ...…...

解释RestFUL API,以及如何使用它构建web程序

RESTful API&#xff08;Representational State Transfer&#xff09;是一种基于网络的软件架构风格&#xff0c;用于构建分布式系统。它利用 HTTP 协议中的各种方法&#xff08;如 GET、POST、PUT、DELETE&#xff09;来对资源进行操作&#xff0c;使得不同应用程序能够相互通…...

文件下载输出zip文件

文件下载输出成zip文件&#xff1a; 1、前端整个按钮&#xff0c;调js方法&#xff1a;&#xff08;参数&#xff1a;param,需要下载的id&#xff0c;用逗号拼接&#xff09; var param "?dto.id";//需要自己拼接param window.location.href "<%basePat…...

构建高效数据流转的 ETL 系统:数据库 + Serverless 函数计算的最佳实践

作者&#xff1a;柳下 概述 随着企业规模和数据量的增长&#xff0c;数据的价值越来越受到重视。数据的变化和更新变得更加频繁和复杂&#xff0c;因此及时捕获和处理这些变化变得至关重要。为了满足这一需求&#xff0c;数据库 CDC&#xff08;Change Data Capture&#xff…...

鸿蒙开发(二)- 鸿蒙DevEco3.X开发环境搭建

上篇说到&#xff0c;鸿蒙开发目前势头旺盛&#xff0c;头部大厂正在如火如荼地进行着&#xff0c;华为也对外宣称已经跟多个厂商达成合作。目前看来&#xff0c;对于前端或客户端开发人员来说&#xff0c;掌握下鸿蒙开发还是有些必要性的。如果你之前是从事Android开发的&…...

Openslide安装

文章目录 安装open-slide python下载openslide二进制文件解压到Anaconda的library目录下配置环境变量在py文件中添加以下语句即可 官网链接 安装open-slide python 表面上这样就可以导入了但事实上会遇到 Couldn’t locate OpendSlide DLL的问题&#xff0c;openslide必须独立安…...

【ES】Elasticsearch常见问题与解决(持续更新)

目录 Elasticsearch常见问题 1. 集群健康问题 2. 性能问题 3. 映射问题 4. 分片问题 5. 内存问题 6. 硬件问题 7. 配置问题 8. 安全问题 9. 网络问题 10. 版本不兼容 Elasticsearch日常使用小结 【Q】离线告警&#xff0c;有IP已离线 【Q】统计某个应用的某个索引…...

2023.12.29 Python面向对象 封装_继承_多台

目录 1.封装-私有与公开权限 2.继承 2.1多继承 2.2继承多层传递 2.3重写父类方法 2.4继承链 2.5禁止私有继承 3.多态 4.总结 1.封装-私有与公开权限 公开属性、公开方法&#xff1a;随便调用 私有属性、私有方法&#xff1a; 只能在类定义的内部调用 以两个下划线开头__的…...

通过自然语言处理增强推荐系统:协同方法

一、介绍 自然语言处理 (NLP) 是人工智能的一个分支&#xff0c;专注于使机器能够以有意义且有用的方式理解、解释和响应人类语言。它包含一系列技术&#xff0c;包括情感分析、语言翻译和聊天机器人。 另一方面&#xff0c;推荐系统&#xff08;RecSys&#xff09;是旨在向用户…...

大创项目推荐 深度学习OCR中文识别 - opencv python

文章目录 0 前言1 课题背景2 实现效果3 文本区域检测网络-CTPN4 文本识别网络-CRNN5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习OCR中文识别系统 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;…...

Python经典游戏 唤醒你童年记忆

这些游戏你玩过几个&#xff1f; 1.贪吃蛇2.吃豆人3.加农炮4.四子棋5. Fly Bird<font color #f3704ab>6.记忆&#xff1a;数字对拼图游戏&#xff08;欢迎挑战&#xff01;用时&#xff1a;2min&#xff09;7.乒乓球8.上课划水必备-井字游戏&#xff08;我敢说100%的人都…...

什么是骨传导耳机?骨传导能保护听力吗?

骨传导耳机是一种非常特殊的蓝牙耳机&#xff0c;它通过骨传导技术将声音直接传送到内耳。这种技术不同于传统耳机&#xff0c;它不通过空气传送声音&#xff0c;而是通过头骨的振动来传送声音。 并且骨传导耳机能够在一定程度上起到保护听力的作用&#xff0c;主要是因为它们不…...

使用electron属性实现保存图片并获取图片的磁盘路径

在普通的网页开发中&#xff0c;JavaScript由于安全性的考虑&#xff0c;通常是无法直接获取到客户端的磁盘路径的。浏览器出于隐私和安全原因对此类信息进行了限制。 在浏览器环境下&#xff0c;JavaScript主要通过Web APIs来与浏览器进行交互&#xff0c;而这些API通常受到浏…...

进击的奶牛

题目 进击的奶牛 题意 通过二分查找算法找到一个最小间距x&#xff0c;使得在数组a中选出的k个数两两之间的间距都不小于x&#xff0c;并且x尽可能大。最后输出这个最大的x值。 思路 程序通过循环依次获取了n个整数&#xff0c;存储在数组a中。.然后&#xff0c;程序对数组a进…...

12月27日,每日信息差

以下是2023年12月27日的8条信息差 第一、小米公司&#xff1a;小米汽车正式加入小米“人车家全生态”&#xff0c;随着小米汽车的即将发布&#xff0c;小米“人车家全生态”也实现了真正闭环 第二、吉利将于2024年初发射11颗卫星&#xff0c;吉利银河E8率先搭载卫星通信技术。…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...

Appium下载安装配置保姆教程(图文详解)

目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...

【Java多线程从青铜到王者】单例设计模式(八)

wait和sleep的区别 我们的wait也是提供了一个还有超时时间的版本&#xff0c;sleep也是可以指定时间的&#xff0c;也就是说时间一到就会解除阻塞&#xff0c;继续执行 wait和sleep都能被提前唤醒(虽然时间还没有到也可以提前唤醒)&#xff0c;wait能被notify提前唤醒&#xf…...

二叉树-144.二叉树的前序遍历-力扣(LeetCode)

一、题目解析 对于递归方法的前序遍历十分简单&#xff0c;但对于一位合格的程序猿而言&#xff0c;需要掌握将递归转化为非递归的能力&#xff0c;毕竟递归调用的时候会调用大量的栈帧&#xff0c;存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧&#xff0c;而非…...

vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能

vxe-table vue 表格复选框多选数据&#xff0c;实现快捷键 Shift 批量选择功能 查看官网&#xff1a;https://vxetable.cn 效果 代码 通过 checkbox-config.isShift 启用批量选中,启用后按住快捷键和鼠标批量选取 <template><div><vxe-grid v-bind"gri…...