async和await

async和awaitasync和await概念先从字面意思来理解。async是“异步”的简写,而await可以认为是asyncwait的简写。所以应该很好理解async用于申明一个function是异步的,而await用于等待一个异步方法执行完成。另外还有一个很有意思的语法规定,await只能出现在async函数中。然后细心的朋友会产生一个疑问,如果await只能出现在async函数中,那这个async函数应该怎么调用?如果需要通过await…

大家好,又见面了,我是你们的朋友全栈君。

async和await 概念

     先从字面意思来理解。async 是“异步”的简写,而 await 可以认为是 async wait 的简写。所以应该很好理解 async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。

    另外还有一个很有意思的语法规定,await 只能出现在 async 函数中。然后细心的朋友会产生一个疑问,如果 await 只能出现在 async 函数中,那这个 async 函数应该怎么调用?

     如果需要通过 await 来调用一个 async 函数,那这个调用的外面必须得再包一个 async 函数,然后……进入死循环,永无出头之日……

  再来说说async有什么作用。

async的作用

       这个问题的关键在于,async 函数是怎么处理它的返回值的!

用return吗?那await做什么呢?试一下。

async和await 

看结果,我们知道返回的是一个promise对象。

async和await

      所以我们从中知道,async 函数返回的是一个 Promise 对象。async 函数(包含函数语句、函数表达式)会返回一个 Promise 对象,如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。

      async 函数返回的是一个 Promise 对象,所以在最外层不能用 await 获取其返回值的情况下,我们当然应该用原来的方式:then() 链来处理这个 Promise 对象,试一下

async和await

输出结果 ⬇

async和await 

 如果async函数没有返回值会报错吗?该返回什么?

 async和await

async和await 

  不会报错,直接返回undefined。

    在没有 await 的情况下执行 async 函数,它会立即执行,返回一个 Promise 对象,并且,绝不会阻塞后面的语句。这和普通返回 Promise 对象的函数并无二致。

那await是做什么用的:

    可以认为 await 是在等待一个 async 函数完成。await 等待的是一个表达式,这个表达式的计算结果是 Promise 对象或者其它值(换句话说,就是没有特殊限定)。

    因为 async 函数返回一个 Promise 对象,所以 await 可以用于等待一个 async 函数的返回值——这也可以说是 await 在等 async 函数,但要清楚,它等的实际是一个返回值。注意到 await 不仅仅用于等 Promise 对象,它可以等任意表达式的结果,所以,await 后面实际是可以接普通函数调用或者直接量的。找一个例子试试看。

 async和await

返回结果

async和await 

await等到结果之后呢?

     await 等到了它要等的东西,一个 Promise 对象,或者其它值,然后呢?我不得不先说,await 是个运算符,用于组成表达式,await 表达式的运算结果取决于它等的东西。

    如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。

    如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

    其实这就是 await 必须用在 async 函数中的原因。async 函数调用不会造成阻塞,它内部所有的阻塞都被封装在一个 Promise 对象中异步执行。

async/await帮我们做了啥?

先做个简单的比较吧 ⬇

    之前已经说明了 async 会将其后的函数的返回值封装成一个 Promise 对象,而 await 会等待这个 Promise 完成,并将其 resolve 的结果返回出来。

举个例子,用 setTimeout 模拟耗时的异步操作,先来看看不用 async/await 会怎么写

async和await

 再试试async/await

async和await

 

    我们看到 takeLongTime() 没有申明为 async。实际上,takeLongTime() 本身就是返回的 Promise 对象,加不加 async 结果都一样。

    又一个疑问产生了,这两段代码,两种方式对异步调用的处理(实际就是对 Promise 对象的处理)差别并不明显,甚至使用 async/await 还需要多写一些代码,那它的优势到底在哪?

async/await的优势在于处理 then:

    单一的 Promise 链并不能发现 async/await 的优势,但是,如果需要处理由多个 Promise 组成的 then 链的时候,优势就能体现出来了(Promise 通过 then 链来解决多层回调的问题,现在又用 async/await 来进一步优化它)。

    假设一个业务,分多个步骤完成,每个步骤都是异步的,而且依赖于上一个步骤的结果。我们仍然用 setTimeout 来模拟异步操作:

async和await

 现在用promise实现这三个步骤的处理async和await

输出结果

async和await

 结果和之前的 Promise 实现是一样的,但是这个代码看起来是不是清晰得多,几乎跟同步代码一样

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/159247.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Client ID认证「建议收藏」

    Client ID认证「建议收藏」1.插件ClientID认证使用配置文件预设客户端ClientID与密码,支持通过HTTPAPI管理认证数据。ClientID认证不依赖外部数据源,使用上足够简单轻量,使用该种认

  • python面对对象

    python面对对象

  • 关于DLL注入的理解

    关于DLL注入的理解DLL注入方式较多,包括API拦截与替换、消息钩子、远程进程。这些注入都是针对第三方程序(下面简称目标程序)的操作。目标程序主要分为两种,解释型和编译型。解析型可以在解释权解释之前做很多事情,比较简单,也比较可行。编译型则无法在编译前做任何事情,因为目标程序一般是第三方编译完成之后发布出来的。编译完成后就是二进制代码(即使能反汇编),就不存在变量名、函数名等标识符,因为这些标识符已经转换成响应的地址。这种情况下,如果拿不到真正的地址,则即使注入到主线程(UI线程)中,依然没有任何作用。除非程序调用的dll包

  • 计算机网络之ip、子网掩码、网络号、主机号等概念解析

    计算机网络之ip、子网掩码、网络号、主机号等概念解析在工作中谈论到计算机网络时,有几个经常出现的术语,比如:ip、子网掩码、网段等等。之前对这些概念的理解都比较模糊,只知其大概意思,随着工作中遇到的网络问题越来越多,有必要详细理解一下计算机网络的基础知识了。这篇文章就先介绍几个计算机网络领域的专业术语。IP地址ip这个词是计算机网络中出现频率最高的了,甚至只要使用过电脑的人都知道这个词。IP地址全程是互联网协议地址(英文:InternetPr…

  • 关于getClass().getClassLoader()

    关于getClass().getClassLoader()InputStream  is  =  getClass().getClassLoader().getResourceAsStream(“helloworld.properties”);中getClass()和getClassLoader()都是什么意思呀.getClass():取得当前对象所属的Class对象  getClassLoader():取得该Class对象的类装载器类装载器

  • EFI和EFI Shell命令简介[通俗易懂]

    EFI和EFI Shell命令简介[通俗易懂]EFI是ExtensibleFirmwareInterface的缩写,是介于平台固件和操作系统之间的一层软件接口。EFI是Intel在1998年开始的一个项目演变而来,而在2005年Intel将EFI1.10开源并交由UnifiedEFI开源社区去维护和开发,Intel自己的EFI也就不单独做了,都和开源社区共用一个。现在也通常用EFI来代指UEFI,二者不再有意区分。EFIShell

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号