【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、 比如给子组件赋值,子组件无法得到这个值(也不是一直无法得到,设置后this.$forceUpdate() 居然可以得到), 更无法watch到 <zizujian :config"_config1"> </zizujian>this._config1 { ...…...
解释RestFUL API,以及如何使用它构建web程序
RESTful API(Representational State Transfer)是一种基于网络的软件架构风格,用于构建分布式系统。它利用 HTTP 协议中的各种方法(如 GET、POST、PUT、DELETE)来对资源进行操作,使得不同应用程序能够相互通…...

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

构建高效数据流转的 ETL 系统:数据库 + Serverless 函数计算的最佳实践
作者:柳下 概述 随着企业规模和数据量的增长,数据的价值越来越受到重视。数据的变化和更新变得更加频繁和复杂,因此及时捕获和处理这些变化变得至关重要。为了满足这一需求,数据库 CDC(Change Data Captureÿ…...

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

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

【ES】Elasticsearch常见问题与解决(持续更新)
目录 Elasticsearch常见问题 1. 集群健康问题 2. 性能问题 3. 映射问题 4. 分片问题 5. 内存问题 6. 硬件问题 7. 配置问题 8. 安全问题 9. 网络问题 10. 版本不兼容 Elasticsearch日常使用小结 【Q】离线告警,有IP已离线 【Q】统计某个应用的某个索引…...
2023.12.29 Python面向对象 封装_继承_多台
目录 1.封装-私有与公开权限 2.继承 2.1多继承 2.2继承多层传递 2.3重写父类方法 2.4继承链 2.5禁止私有继承 3.多态 4.总结 1.封装-私有与公开权限 公开属性、公开方法:随便调用 私有属性、私有方法: 只能在类定义的内部调用 以两个下划线开头__的…...

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

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

Python经典游戏 唤醒你童年记忆
这些游戏你玩过几个? 1.贪吃蛇2.吃豆人3.加农炮4.四子棋5. Fly Bird<font color #f3704ab>6.记忆:数字对拼图游戏(欢迎挑战!用时:2min)7.乒乓球8.上课划水必备-井字游戏(我敢说100%的人都…...

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

使用electron属性实现保存图片并获取图片的磁盘路径
在普通的网页开发中,JavaScript由于安全性的考虑,通常是无法直接获取到客户端的磁盘路径的。浏览器出于隐私和安全原因对此类信息进行了限制。 在浏览器环境下,JavaScript主要通过Web APIs来与浏览器进行交互,而这些API通常受到浏…...
进击的奶牛
题目 进击的奶牛 题意 通过二分查找算法找到一个最小间距x,使得在数组a中选出的k个数两两之间的间距都不小于x,并且x尽可能大。最后输出这个最大的x值。 思路 程序通过循环依次获取了n个整数,存储在数组a中。.然后,程序对数组a进…...
12月27日,每日信息差
以下是2023年12月27日的8条信息差 第一、小米公司:小米汽车正式加入小米“人车家全生态”,随着小米汽车的即将发布,小米“人车家全生态”也实现了真正闭环 第二、吉利将于2024年初发射11颗卫星,吉利银河E8率先搭载卫星通信技术。…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...