你真的会用async和await么?

async函数搞懂

  • 背景
  • async
  • await
    • await 知识点1
    • await 知识点2
    • await 知识点三
    • await 知识点四
    • await 知识点五

背景

背景就是遇到了一个比较烦人的模块,里面的涉及到了大量的async 和 awiat。发现大多人对这个语法糖一知半解,然后大量的滥用,整理一下

async

前置知识:

 Promise.resolve('foo)   ===    new Promise(resolve => resolve('foo'))Promise.reject('foo)    ===  new Promise((resolve, reject) => reject('出错了'))

1、async修饰的函数返回一个promise

async function myName() {let result = await Promise.resolve("hello")let result1 =  await Promise.resolve("hello1")console.log(result)console.log(result1)
}
myName().then(e => console.log(e))
//hello
//hello1
//undefined (函数没有返回任何的值所以是undefined)---------------------
async function myName() {let result = await Promise.resolve("hello")let result1 =  await Promise.resolve("hello1")return ({result,result1})
}
myName().then(e => console.log(e))
// { result: 'hello', result1: 'hello1' }

2、async返回的是一个promise,当async中发生错误,这个错误会使返回的promise变为reject状态,从而可以被,catch捕捉到

async function sayHi() {throw new Error('抛出一个错误')
}
// 以下四种写法是等价的
sayHi().then(e => console.log(e),e =>console.log(e))
sayHi().then(undefined,e =>console.log(e))
sayHi().then().catch(res => console.log(res))
sayHi().catch(res => console.log(res))

3、注意以下用法,以下用法在项目中使用是极多的

i:以下的这种写法就很好理解了,没问题的

function timeout(ms) {return new Promise((resolve) => {setTimeout(resolve, ms);});
}
async function asyncPrint(value, ms) {await timeout(ms);console.log(value);
}asyncPrint('hello world', 50)
// hello world

ii:因为async返回一个promise,所以下述写法完全等同于i的写法

async function timeout(ms) {await new Promise((resolve) => {setTimeout(resolve, ms);});
}
async function asyncPrint(value, ms) {await timeout(ms);console.log(value);
}
asyncPrint('hello world', 50)
// hello world

在这里插入图片描述

async function timeout(ms) {await new Promise((resolve) => {setTimeout(resolve, ms);});console.log(8888)
}
async function asyncPrint(value, ms) {let res =  timeout(ms)console.log(res) console.log(value);
}
asyncPrint('hello world', 50)
// Promise { <pending> }
// hello world
// 8888
async function timeout(ms) {await new Promise((resolve) => {setTimeout(resolve, ms);});console.log(8888)
}async function asyncPrint(value, ms) {let res =  timeout(ms)console.log(res) await timeout(ms);console.log(value);
}
asyncPrint('hello world', 50)
//Promise { <pending> }
// 8888
// 8888
// hello world
async function timeout(ms,b=2) {await new Promise((resolve) => {setTimeout(resolve, ms);});console.log(8888,b)
}async function asyncPrint(value, ms) {let res =  timeout(ms,9)console.log(res) await timeout(ms,6);console.log(value);}
asyncPrint('hello world', 5000)
//Promise { <pending> }
//8888 9
//8888 6
//hello worl

以下对比:async await 修饰的A函数内部执行时序肯定是可控的,但是如果想要在 另一个函数B中也可控(也就是B中调用了A,想让A执行完,在执行B的一些逻辑,那么就需要用awiat来修饰A)

async function timeout(ms) {await new Promise((resolve) => {setTimeout(resolve, ms);});
}
async function asyncPrint(value, ms) {await timeout(ms);console.log(value);
}
asyncPrint('hello world', 5000);
// 5s后会打印 'hello world'
-------------------------------
async function timeout(ms) {await new Promise((resolve) => {setTimeout(resolve, ms);});
}
function asyncPrint(value, ms) {timeout(ms);console.log(value);
}
asyncPrint('hello world', 5000);
// 直接就打印'hello world',并不等5s
-----------------------
async function timeout(ms) {await new Promise((resolve) => {setTimeout(resolve, ms);});console.log("打印时机")
}
function asyncPrint(value, ms) {timeout(ms);console.log(value);
}
asyncPrint('hello world', 5000);
// 立马打印'hello world',5s后打印 '打印时机'

await

await命令只能用在async函数之中,用在普通函数中会报错

await 知识点1

  • await 命令后面是一个promise对象(可以返回这个promise的resolve时的结果并且可以接收,但是reject时就不可以接收到了会报错(可以利用try catch捕捉到reject的结果,或者使用promise的catch可以捕捉到))
  • await后面是简单数据或者负责数据,其实都相当于直接把该值给return出来
async function f() {return await 123
}
f().then(e => {console.log(e)})
// 123async function f() {return 123
}
f().then(e => {console.log(e)})
// 123async function f1() {return await {sex: 'man'}
}
f1().then(e => {console.log(e)})
// { sex: 'man' }async function f2() {await {sex: 'man'}
}
f2().then(e => {console.log(e)})
// undefined

await 知识点2

await后面的promise失败了,如何获取到这个失败的值。async里面如果有多个await修饰的promise,返回的resolve的promis并不会阻塞,会继续往下走,但是遇到reject的promise就会直接return出去(有时我们甚至不需要写return)

async function f() {return await Promise.resolve('对了');
}
f()
.then(v => console.log(v))
.catch(e => console.log(e))
// 对了

await语句前面没有return,但是reject方法的参数依然传入了catch方法的回调函数。这里如果在await前面加上return,效果是一样的。

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

await 知识点三

  • await修饰异步,在async中使用,当promise是resolve时接着往下走
  • 任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。

1、awiat(直接用),只能接收resolve返回的参数

async function myName() {let result = await Promise.resolve("hello")let result1 = await Promise.resolve("hello1")console.log(result)console.log(result1)
}
myName()
// hello
// hello1
async function myName1() {let result = await Promise.reject("hello")console.log(result)
}
myName1()
// 报错了
------------
async function myName1() {let result = await Promise.reject("hello")console.log(111111111111111)console.log(result)
}
myName1()
// 报错了(console都没走)

2、搭配 try catch 可以用 catch捕捉到reject的错误

async function myName2() {try {let result = await Promise.reject("hello")console.log(result)} catch (error) {console.log('出错了',error)}
}
myName2()
// 出错了 hello

3、try catch ,try内之要有一个promise reject,那么后续的就都不会进行了,直接将第一个reject给catch给出去了

async function myName2() {try {let result = await Promise.reject("hello")console.log(result)let result1 = await Promise.resolve("hello word")console.log(result1)} catch (error) {console.log('出错了',error)}
}
myName2()
// 出错了 hello
----------------------------------------
// 下方demo为了证明,报错后没有再往后走
async function myName2() {try {await Promise.reject("hello")console.log('走不走')let result1 = await Promise.resolve("hello word")console.log(result1)} catch (error) {console.log('出错了',error)}
}
myName2()
// 出错了 hello

myName()返回一个promise,这个promise是reject,所以 f函数里的await后面修饰的也就是一个失败的reject了

async function myName() {throw new Error('抛出一个错误');
}
async function f() {await myName()
}f()
.then(v => console.log(v))
.catch(e => console.log(e))
// Error: 抛出一个错误

await 知识点四

如何解决一个async函数中有多个await,而当一个await reject时,怎么保证接下来的await继续往下走(当然这种场景一般是不会存在哈,如果前后异步没有依赖的话(学到个名次(这种关系叫做—继发)),为何要控制他们时序呢?正是因为有依赖所以才要控制时序,既然有依赖关系,第一个失败了,按道理后续就是不应该继续执行了)

// 上述演示过这个场景,可以看到只要一个错误,就不往下走了
// 任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行
async function f() {await Promise.reject('出错了')console.log('判断是否走不走')await Promise.reject('接着出错')
}
f().then().catch(e => console.log(e)) 
// 出错了
  • 思路: 用catch处理一下reject,将错误处理一下,那么catch就不会暴露出去了

解决方案1:

async function k() {try {await Promise.reject('出错了')}catch(e) {console.log(e)}try {await Promise.reject('出错了1')}catch(e) {console.log(e)}await Promise.reject('接着出错')
}
k().catch(e => console.log(e))
// '出错了'
// '出错了1'
// '接着出错'

解决方案2:

async function l() {await Promise.reject('出错了').catch(e => console.log(e))await Promise.reject('出错了1').catch(e => console.log(e))await Promise.reject('出错了2').catch(e => console.log(e))await Promise.reject('接着出错')
}
l().catch(e => console.log(e))
//出错了
//出错了1
//出错了2
//接着出错

await 知识点五

问:await后面的错误如何处理?
答:如果await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject

sync function y() {await new Promise((resolve,reject) => {throw new Error('出错了')})
}
y().catch(e => console.log(e))
// Error: 出错了

错误捕捉(获取)(上面也提到了,分为两种1、try catch 2、用catch捕捉)

async function j() {await new Promise((resolve,reject) => {throw new Error('出错了')}).catch(e => console.log(e))
}
j()
// Error: 出错了
async function j() {try {await new Promise((resolve,reject) => {throw new Error('出错了')})} catch(e) {console.log(e)}
}
j()
// Error: 出错了

分割线------------------------------------------------------


   function name() {try {throw new Error('出错了');console.log(1111);} catch (e) {console.log(e);}}

如果抛出错误 throw new Error 就不在往下走了,不会执行执行打印,走到了catch

    async onSubmit() {this.lastClickEvent = this.CLICK_EVENT.ADD;try {await this.commonAdd();this.$message({type: 'success',message: this.$t('msg_success')});if (this.isClient) {this.SynchronizeResourceUpdate();}if (!this.accessGuide) {this.back();}} catch (error) {console.log(error);}},

commonAdd如果有throw new Error也就不往下走了,try catch被中断

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

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

相关文章

数据标注的类型有哪些?

构建像人类一样的AI或ML模型需要大量训练数据。要使模型做出决定并采取行动&#xff0c;就必须通过数据标注来训练模型&#xff0c;使其能够理解特定信息。 但是&#xff0c;什么是数据标注呢&#xff1f;数据标注是指对用于人工智能应用的数据进行分类和标注。我们必须针对特定…

Qt6 Qt Quick UI原型学习QML第二篇

Qt6 Qt Quick UI原型学习QML第二篇 界面效果QML语法语法讲解核心要素项目元素矩形元素文本元素图像元素MouseArea元素 界面效果 QML语法 import QtQuick 2.12 import QtQuick.Window 2.12Window {id: rootvisible: truewidth: 640height: 480title: qsTr("QML学习第二篇&…

用微服务架构推进企业数字化转型升级

随着数字化转型进入深水区&#xff0c;企业应用程序建设需求急剧增长且变化多端&#xff0c;软件架构经历了单体结构、垂直架构、SOA架构&#xff0c;发展到了现在的微服务架构。 单体架构目前应用较多&#xff0c;部署容易&#xff0c;但单体式应用内部包含了所有需要的服务&…

FPGA——点亮led灯

文章目录 一、实验环境二、实验任务三、实验过程3.1 编写verliog程序3.2 引脚配置 四、仿真4.1 仿真代码4.2仿真结果 五、实验结果六、总结 一、实验环境 quartus18.1 vscode Cyclone IV开发板 二、实验任务 每间隔1S实现led灯的亮灭&#xff0c;实现流水灯的效果。 三、实…

基于卡尔曼滤波进行四旋翼动力学建模(SimulinkMatlab)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

2.Docker镜像和容器操作

文章目录 Docker操作Docker镜像操作搜索镜像获取镜像镜像加速下载查看镜像详细信息为镜像添加标签删除镜像导出导入镜像上传镜像 Docker容器操作创建容器查看容器状态启动容器创建并启动容器进入容器停止容器删除容器复制容器文件到宿主机容器的导出导入 Docker操作 ###查看do…

vscode 端口转发实现端口映射,实现端口自由

用vscode连接server进行开发&#xff0c; 是非常方便的&#xff0c;但很多时候&#xff0c;server的端口开放的很有限&#xff0c;那么就可以利用vscode进行端口映射 举一个应用场景&#xff1a; 先通过A利用vscode 连接B&#xff0c;然后再vscode 的port窗口进行端口转发&…

SpringBoot中整合Sharding Sphere实现数据加解密/数据脱敏/数据库密文,查询明文

场景 为防止数据泄露&#xff0c;需要在插入等操作时将某表的字段在数据库中加密存储&#xff0c;在需要查询使用时明文显示。 Sharding Sphere ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈&#xff0c; 它由Sharding-JDBC、Sharding-Proxy和Shardi…

如何获取microstore商品详情接口php接口jason数据字段

随着科技的发展&#xff0c;API接口成为了各行业发展的最新趋势。在微店购物平台中&#xff0c;商品详情API接口的引入&#xff0c;为商家和消费者提供了更加便捷、高效的用户体验。本文将为大家详细介绍微店商品详情API接口的优势和使用方法 商品详情API接口的优势 1.提升用户…

【milvus】向量数据库,用来做以图搜图+人脸识别的特征向量

1. 安装milvus ref:https://milvus.io/docs 第一次装东西&#xff0c;要把遇到的问题和成功经验都记录下来。 1.Download the YAML file wget https://github.com/milvus-io/milvus/releases/download/v2.2.11/milvus-standalone-docker-compose.yml -O docker-compose.yml看…

JavaWeb项目【SpringBoot】——图书项目4.0【源码】:SpringBoot版本 springboot相关技术 项目应用

目录 项目简介思考 & 改进1.Jsp都是同步请求---->改成异步Ajax【完成】2.前端用Jsp技术落后----->用Vue框架【完成】3.架构问题&#xff1a;配置数据和Java代码耦合【完成】3.SQL语句和Java代码耦合【完成】4.架构问题&#xff1a;servlet只能处理一个请求5.响应方式…

Web前端工程师笔试题(合集)

Web前端开发工程师笔试题篇1 1. 在一个框架的属性面板中&#xff0c;不能设置下面哪一项。( C ) A.源文件 ; B.边框颜色 ; C.边框宽度 D.滚动条 2. CSS样式表根据所在网页的位置&#xff0c;可分为?(B ) A.行内样式表、内嵌样式表、混合样式表 B.行内样式表、内嵌样式表…

客户案例 | 数字化加速,金融企业实现3D打印式应用程序开发

关键发现&#xff1a; 客户痛点&#xff1a;传统开发周期长&#xff0c;流程复杂&#xff0c;难以满足杭银消金在企业快速发展过程中的应用开发需求&#xff1b;内部业务因为优先级不高&#xff0c;导致开发资源分配有限&#xff0c;更加迟滞了管理部门数字化转型的进度。 解决…

pytorch实现线性回归

转大佬笔记 代码&#xff1a; # -*- coding: utf-8 -*- # Time : 2023-07-14 14:57 # Author : yuer # FileName: exercise05.py # Software: PyCharm import matplotlib.pyplot as plt import torch# x,y是3行1列的矩阵&#xff0c;所以在[]中要分为3个[] x_data torch.…

03 QT对象树

Tips: QT通过对象树机制&#xff0c;能够自动、有效的组织和管理继承自QObject的Qt对象&#xff0c;不需要用户手动回收资源&#xff0c;系统自动调用析构函数。 验证对象树功能&#xff1a; 新建C文件 继承自QPushButton&#xff0c;但没有QPushButton&#xff0c;但有其父类…

谷歌Bard更新:支持中文提问和语音朗读

ChatGPT不断更新功能&#xff0c;从GPT-3到3.5&#xff0c;再到GPT-4&#xff0c;甚至最新的plus版已经支持图像处理和图表生成&#xff0c;而谷歌Bard却自从推出后就一直很安静&#xff0c;没有什么大动作。眼见被ChatGPT、Claude甚至是文心一言抢去了风头&#xff0c;自然心有…

050、事务设计之Percolator事务模型

Percolator 背景 Bigtable: 大表打散每行到各个节点&#xff0c;每一行作为一个kv。解决的问题 一个事务涉及的行在多个节点&#xff0c;如何用单行对一个事务进行控制&#xff0c;实现原子性。 快照隔离级别&#xff08;snapshot &#xff09; 白色点&#xff1a;代表事务开始…

Bring Your Data!Self- supervised Evolution of Large Language Models

Bring Your Data&#xff01;Self- supervised Evolution of Large Language Models IntroductionMethod参考 Introduction 这篇论文提出了一种自监督的评估方式来衡量大型语言模型的能力和局限性。常规的基于数据集的评估方式存在一些缺点: 需要不断新建数据集。存在数据集和…

不用显示器,不用鼠标和键盘,让我们用主机远程访问OK3588的桌面

不用显示器&#xff0c;不用鼠标和键盘&#xff0c;让我们用主机远程访问OK3588的桌面 MobaXterm软件介绍串口终端运行命令MobaXterm访问开发板 MobaXterm软件介绍 MobaXterm是一款增强型终端软件&#xff0c;对于Windows平台上的程序员、网络管理员和开发者是一款极其优秀的工…

TCP缓冲区和4次挥手调优

目录 如何修改TCP缓冲区才能兼顾并发数量与传输速度&#xff1f; 四次挥手性能调优 1,为什么建立连接是三次握手&#xff0c;而关闭连接需要四次挥手呢? 2.四次挥手的流程,注意5个状态 3.主动方优化 4,被动方调优 最后 如何修改TCP缓冲区才能兼顾并发数量与传输速度&…