ES8新特性之async函数与await表达式(常见疑惑解答)

2023-05-16

说明:在学习了async和await后,很多人往往不知道这两个人是干什么的,对于这两个重要角色的使用方式和原理都比较模糊,下面为大家介绍这两个角色的语法,后面附有两个小例子,能够让大家明白async和await的作用以及使用场景。

简介:async和await两种语法结合可以使得异步代码像同步代码一样使用。
关于async函数:
简介:实质上就是在普通函数前添加上async关键字进行修饰的函数。
此种函数被称为async函数,且其返回值必定为一个Promise对象。
Promise对象的状态依据async函数的返回值情况决定:
1,当async函数的返回值非“Promise对象”时:
函数的返回值为一个成功的Promise对象。
2,当async函数的返回值为Promise对象时:
函数的返回值的Promise对象是否成功由返回值的Promise对象决定
3,当async函数的返回值抛出错误时:
函数的返回值为一个失败的Promise对象。

格式:“ async function 方法名 ( ) { //方法体 } ”
例子

async function func(){
    //方法体
    return new Promise(function(resolve,reject){
        //Promise实例构造函数参数的方法体
        if(xxxx){
            resolve("参输内容");
        }else{
            reject("参数内容");
        }
    })
}
//调用async函数,获取其返回的Promise对象
const promiseFromFunc = func();
promiseFromFunc.then(
    function(resolve){
        //成功时执行的方法体
    },
    function(reject){
        //失败时执行的方法体
    }
)

关于await表达式:
简介:对于await表达式,是有使用的前提条件的,前提条件如下:
1,await必须写在async函数中
2,await修饰的一般为一个Promise对象
3,await返回的是Promise的成功值,相当于Promise中then方法的首参数的函数
即:await所修饰的Promise对象会返回该Promise对象所调用resolve()方法时
所传入resolve()方法中的成功的参数内容。
4,await修饰的promise对象必须由try…catch修饰,以接收Promise的错误值。
即:try…catch会捕捉await所修饰的Promise对象所调用reject()方法时
所传入reject()方法中的失败的参数内容。
(以上几条很重要,请认真看。)

例子:

async function func(){
    
    try{
        //此处可以使整个函数直接返回由await修饰的Promise实例的构造方法的返回值
        //也可以不返回值而使用一个变量接收Promise实例的构造方法的返回值,
        //然后传递给方法体之外的变量。
        
        //写法1
        return await new Promise((resolve,reject)=>{
            //Promise函数体
            //此处根据自定义的条件调用resolve或reject
        
        })
        //写法2
        let a = await new Promise((resolve,reject)=>{
            //Promise函数体
            //此处根据自定义的条件调用resolve或reject
        
        }) 
    }catch(e){
        console.log(e);
    }
}

关于async和await自己的理解:
由于async函数的返回值是一个Promise对象,
这就决定了async函数中的await所修饰的一定是一个Promise对象。
await修饰Promise可达到的效果为:对同步代码实行线程阻塞,
等待Promise实例的构造方法中的resolve()方法或reject()方法执行完毕后,
再执行await之后的同步代码。
(注意:Promise本身不是异步方法,其构造函数也不是异步方法,由await修饰后,
线程会等待Promise执行完毕后才会继续执行之后的代码。当Promise的状态被决定后,
则判定Promise已被执行完毕。)

async和await解决了什么问题?
以一个“异步请求数据不同步”的问题来说明。异步请求数据不同步的问题是指
现需求异步请求数据,将数据渲染至页面上,以一般思路来讲,代码可能如下:

let a = null;//a方法外的一个全局变量,用于作为渲染数据的中间变量
function getNews(){
    //定义一个获取信息的方法,并在该方法下发送异步请求
    $.post('./databaseConn.php',{},function (res){
        if (res !== null){
            res = JSON.parse(res);
            a=res.news_content;//此处给a变量赋值,内容为后台所获取到的信息。
        }
    });
    //此处打印a变量,打印结果为null。
    //原因:因为上面是一个post异步请求代码,而console.log是一个同步代码
    //因此,上述请求代码没有执行完毕,console.log代码就已经执行了
    //因为上述异步请求代码还未执行完毕,故a变量还未被赋值,所以打印结果为null
    console.log(a);
}
getNews();

如果使用async方法配合await表达式即可解决上述问题,则代码如下:

let a = null;//a方法外的一个全局变量,用于作为渲染数据的中间变量

async function getNews(){
    //此为一个async方法
    try{
        //此处使用await修饰Promise对象,可以保证Promise中的
        //异步请求操作执行完毕以后再进行await之后的“同步操作”
        a = await new Promise((resolve,reject)=>{
            $.post('./databaseConn.php',{},function (res){
                if (res !== null){
                    res = JSON.parse(res);
                    // console.log(res.news_content);
                    // a=res.news_content;
                    resolve(res.news_content);
                }
            });
        })
    }catch (e) {
        console.error("错误")
    }
    //此处打印a变量,打印结果为请求所赋值的具体数据
    //因为await表达式的修饰,执行到console.log会有一个线程阻塞,
    //从而console.log会等待前面的异步执行操作执行完毕后再执行,
    //前面的异步请求执行完毕以后,变量a就被赋值成功了,从而能够
    //打印处请求到的数据。
    console.log(a)
}
getNews();

总结:上述两段代码都是在异步操作里取值(对a的赋值操作),
第一部分代码由于异步操作的原因,之后的同步操作先被执行了,
因而导致了没取到数据的情况。
而第二部分代码同为在异步操作里取值(对a的赋值操作),操作上是利用了
await会等待Promise执行完毕的特性,
(当resolve方法或reject方法执行完毕时,Promise的状态被确定,
则视Promise执行完毕)。
将resolve方法放在异步操作中取值传参,就可以做到异步操作的同步效果。
即:等待异步操作获取到数据之后再进行后续的其他相关操作的效果。

注意:使用此方法的话,取值必须在异步操作之中,不然依然会出现异步取值为空的问题
因为resolve方法是同步方法,若取值操作不在异步操作中,则异步操作就不会与await的
效果进行相应的绑定,则Promise的构造方法内部并没有起到线程阻塞的效果,
resolve方法会先被执行,从而导致取不到数据的情况。
(总结和注意的内容请认真看,上面都很重要,就不标红字体了)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ES8新特性之async函数与await表达式(常见疑惑解答) 的相关文章

随机推荐

  • 提高虚拟机中使用ubuntu系统的流畅度

    背景 虚拟机 xff1a virtual box6 1ubuntu版本 xff1a 14 04 现象 1 默认主题下 xff0c 编辑代码时 xff0c 会出现很卡的现象 xff08 频率较高 xff09 2 操作界面不流畅 对策 可能虚拟
  • QEMU搭建U-Boot+Linux+NFS 环境 学习笔记

    使用QEMU搭建U Boot 43 Linux 43 NFS嵌入式开发环境 QEMU简介使用QEMU的事情使用QEMU学习嵌入式的好处驱动开发技能搭建嵌入式基本开发环境基本环境Vmware 43 Ubuntu18 04Vmwaretools
  • brctl使用教程

    使用brctl来操作网桥还是很方便的 xff01 比使用ip命令来操作方便多了 brctl安装 Centos系统 yum install bridge utils Ubuntu系统 Debian系 apt get install bridg
  • IntelliJ IDEA 之 配置JDK 的 4种方式

    一 新建项目前配置JDK 打开idea集成开发环境工具 xff0c 点击File gt Project Structure 如下图 xff1a 在打开的页面中 xff0c 选择SDKs属性 xff0c 并点击中间的加号 43 选择JDK x
  • STM32如何在LCD上显示单词、文字、图片等

    本文将介绍STM32F103R6如何在LCD12864上显示文字图片 注 xff1a 本文中用到的字模软件 xff0c 我放在了文章末尾 xff0c 点击链接即可下载 xff0c 是绿色版软件 xff0c 解压即可使用 xff01 点击下载
  • JAVA之Lambda表达式详解

    文章目录 一 基本概念1 背景2 Lambda表达式的语法3 函数式接口 二 Lambda表达式的基本使用1 无返回值函数式接口2 有返回值函数接口3 语法精简 三 变量捕获1 匿名内部类2 Lambda的变量捕获 四 Lambda在集合当
  • 【CUDA】安装CUDA

    文章目录 1 搜索CUDA xff0c 进入官网2 选择以前的版本3 选择指定的版本4 选择操作系统并下载5 以管理员身份运行安装CUDA6 测试是否安装成功 1 搜索CUDA xff0c 进入官网 2 选择以前的版本 3 选择指定的版本
  • 计算机组成原理---系统总线

    文章目录 1 总线的基本概念2 总线的分类2 1 片内总线2 2 系统总线2 2 1 系统总线的定义2 2 2 按照系统总线传输信息的分类2 2 3 通信总线 3 总线的性能指标3 1 总线标准 4 总线结构4 1 单总线结构4 2 多总线
  • 计算机组成原理---总线带宽的计算

    end
  • QT之窗口背景颜色和图片设置

    设置窗口 窗体的背景图片 第一种 xff1a 定义一个函数 xff0c 使用QPalette和QPixmap 在 h文件定义一个私有的函数声明 xff1a void resizeEvent QpesizeEven event 然后右键跳到定
  • linux/mm/memory.c/put_page

    put page用来完成物理页面与一个线性地址页面的挂接 xff0c 从而将一个 线性地址空间内的页面落实到物理地址空间内 xff0c copy page tables函数 只是为一个进程提供了在线性地址空间的一个页表及1024页内存 xf
  • 解决keil软件*** Error: Project ‘first‘ requires ‘C51‘ Toolchain which is not installed.

    在安装好了 xff08 破解 xff09 后的MDK环境后依然无法编译 xff0c 出现 Error Project first requires C51 Toolchain which is not installed 软件安装 一 介绍
  • 计算机网络:第四章习题

    简答题 amp 计算题 4 03 作为中间设备 xff0c 转发器 网桥 路由器和网关有何区别 xff1f 答 xff1a 转发器 xff1a 它工作在物理层 xff0c 主要起信号的放大整形和延迟传输距离的作用 网桥 xff1a 工作在数
  • 【mysql 5.7】最左原则 & like查询%在前为什么不走索引

    文章目录 1 问题的引入2 非覆盖索引场景下为什么 在前为什么不走索引参考 xff1a 1 问题的引入 在非覆盖索引场景下 xff0c 大家知道Mysql索引有最左原则 xff0c 所以通过 like 39 XX 39 查询的时候一定会造成
  • Bottom-Up and Top-Down

    top down xff1a 在模式识别中使用了上下文信息 xff08 机器的处理方式 xff09 举例 xff1a 当你看到一张字迹潦草难以辨认的手写文本时 xff0c 你可以利用整个文本来辅助你理解其中含义 xff0c 而不是每个字单独
  • 浅层与深层、局部与全局、低级与高级特征的辨析

    浅层网络与深层网络 浅层网络更注重于细节信息 深层网络更注重于语义信息 浅层网络 xff1a 一般感受野较小 xff0c 能够利用更多的细粒度特征信息 xff0c 而且此时特征图每个像素点对应的感受野重叠区域还很小 xff0c 这就保证了网
  • ARM交叉编译工具链安装和使用教程【图文并茂】

    ARM交叉编译工具链安装和使用教程 图文并茂 1 交叉编译安装 2 交叉编译使用 1 交叉编译安装 下载 由于嵌入式板卡的软硬件是定制的 xff0c 因此针对其平台开发的程序所需要的编译器也必须与之相匹配 xff1a GEC6818开发板交
  • 关于Jquery index()方法的文字详细解析

    关于Jquery index xff08 xff09 方法的文字详细解析 此函数返回的是一个元素的索引位置 xff0c 索引位置从零开始 若带参数 xff0c index参数可以直接传入jquery选择器进行元素选择 也可以传入字符串进行元
  • ESP8266

    ESP8266 一 xff0c 物联网介绍 物联网 xff0c 即IOT xff08 internet of things xff09 是用网络将万物互联 xff0c 如将汽车 xff0c 温度计 xff0c 咖啡杯等都可以连接到互联网 x
  • ES8新特性之async函数与await表达式(常见疑惑解答)

    说明 xff1a 在学习了async和await后 xff0c 很多人往往不知道这两个人是干什么的 xff0c 对于这两个重要角色的使用方式和原理都比较模糊 xff0c 下面为大家介绍这两个角色的语法 xff0c 后面附有两个小例子 xff