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

async与await异步编程

ECMA2017中新加入了两个关键字async与await

简单来说它们是基于promise之上的的语法糖,可以让异步操作更加地简单明了

首先我们需要用async关键字,将函数标记为异步函数

async function f() {

}
f()

异步函数就是指:返回值为promise对象的函数
比如之前用到的fetch()就是一个异步函数,返回的是promise

在异步函数中,我们可以调用其他的异步函数,不过我们不再需要使用then,而是使用一个await。

await会等待Promise完成之后直接返回最终结果

所以这里的response已经是一个服务器返回的响应数据了

async function f() {
    const response = await fetch("http://....")
}
f()

虽然await看上去会暂停函数的执行,但在等待的过程中,js同样可以处理其他的任务

这是因为await底层是基于promise与事件循环(event loop)机制实现的

await使用时的陷阱:

1、第一个陷阱
比如:我们分别去await这两个异步操作

async function f() {
    const a = fetch("http://..../post/1")
    const b = fetch("http://..../post/2")
}
f()

虽然不存在逻辑错误
但这样会打破这两个fetch()操作的并行
因为我们会等到第一个任务执行完成之后才开始执行第二个任务

这里更高效的方法是将所有的Promise用Promise.all组合起来,然后再去await:

修改之后的执行效率会直接提升一倍

async function f() {
    const promiseA = fetch("http://..../post/1")
    const promiseB = fetch("http://..../post/2")

    const [a, b] = await Promise.all([promiseA,promiseB])
}
f()

2、第二个陷阱

如果我们需要在循环中执行异步操作,是不能够直接调用forEach或者map这一类方法的,尽管我们在回调函数中写了await也不行。

因为这里的forEach会立即返回,它并不会等到所有的异步操作都执行完毕

async function f() {
   [1,2,3].forEach(async (i) => {
    await someAsyncOperation();
   })
   console.log("done")

}
f()

如果我们希望等待循环中的异步操作都一一完成之后才继续执行

我们应当使用传统的for循环

async function f() {
    for( let i of [1,2,3]){
        await someAsyncOperation();
    }
   console.log("done")
}
f()

如果我们希望所有的程序并发执行,一种更炫酷的写法就是使用for await

这里的for循环依然会等到所有的异步操作都完成之后才会继续向后执行

在这里插入图片描述
3、第三个陷阱

我们不能在全局或者普通函数中直接使用await关键字

await只能用在异步函数(async function)中

如果我们想要在最外层中使用await,那么需要先定义一个异步函数:
在这里插入图片描述
使用await async可以让我们写出更清晰,更容易理解的异步代码

参考视频教程:
https://www.bilibili.com/video/BV1WP4y187Tu/?spm_id_from=333.337.search-card.all.click&vd_source=ee0c6018997dd78957dfe36225950357


http://www.kler.cn/a/2088.html

相关文章:

  • 基于Spring Boot的智慧农业专家远程指导系统
  • 【Lua热更新】上篇
  • 游戏渠道假量解决方案
  • FPGA:FPGA器件选型
  • 腾讯云云开发 Copilot 深度探索与实战分享
  • 3.使用SD卡挂载petalinux根文件系统
  • WPF 认识WPF
  • Mybatis的多表操作
  • unity3d游戏运行时lua热重载
  • Kaggle实战入门:泰坦尼克号生还预测(进阶版)
  • Qt cmake 资源文件的加载
  • LeetCode:27. 移除元素
  • ini配置文件
  • Boosting(XGBoost、LightGBM以及CatBoost)
  • 栈、队列、优先级队列的模拟实现
  • 【计算机组成原理】:计算机系统概述
  • 鸟哥的Linux私房菜 Shell脚本
  • 【Leetcode】队列实现栈和栈实现队列
  • 【三维几何学习】从零开始网格上的深度学习-3:Transformer篇(Pytorch)
  • 【Zabbix实战之部署篇】docker部署Zabbix+grafana监控平台
  • 【C++初阶】四、类和对象(下)
  • 沁恒CH32V307使用记录:使用TIM输出PWM信号
  • C++笔记——第六篇 list的简介和使用
  • 多线程 (六) 单例模式
  • 蓝桥杯备赛经验 pythonA组(非科班选手)
  • 拯救会议纪要!快用这三个音频转文字方法,让领导对你刮目相看