目录
- 什么是async?
- async的用法
- 语法解析
- 应用案例
- async 函数的实现原理
一 什么是async?
- 是ES7引入的异步解决方案,使异步操作变得更为方便
- 是Generator函数的语法糖,语法更为简洁,语义更明朗简而言之,async用于申明一个function是异步的;await必须用在异步函数中,等待一个异步方法执行完成。
上图左为Generator的写法,右为async的写法,同为输出promise结果
相较于Generator的优点
- 内置执行器: async内置执行器,不同于Generator函数需要调用next()才能执行;async和普通函数一样执行
- 更好的语义: 相对于*和yield,async和await语义更明朗; async是异步执行函数,await用于async内,等待后面表达式结果;
- 更广的实用性: await后面可以跟promise也可以跟基本数据类型(字符,数值,布尔) 若await后跟基本数据类型,则自动转成resolved的promise对象
- 返回值为promise Generator 函数的返回值是 Iterator(迭代器),async返回值为promise,可以使用then()进行下一步操作,更为方便
二 async的用法
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
上面代码是一个获取股票报价的函数,函数前面的async关键字,表明该函数内部有异步操作。调用该函数时,会立即返回一个Promise对象。
p1: 如果存在C请求的调用需在A/B请求之后,但A/B请求是异步执行,如何应用?
显然使用三个await是不合理的,既然await后可以跟跟promise,那么我们可以使用promise.all来满足此需求
同时,async函数还可以写成以下几种形式
三、语法解析
1. 返回 Promise 对象
async函数返回一个promise对象async函数内部return返回的值,会成为then方法回调函数的参数
上图代码中,函数f内部return命令返回的值,会被then方法回调函数接收到
async函数内部抛出错误,会导致返回的Promise对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到
2. Promise 对象的状态变化
async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。
上面代码中,函数getTitle内部有三个操作:抓取网页、取出文本、匹配页面标题。只有这三个操作全部完成,才会执行then方法里面的console.log。
3. await 命令
正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。
上面代码中,await命令的参数是数值123,这时等同于return 123。
另一种情况是,await命令后面是一个thenable对象(即定义then方法的对象),那么await会将其等同于 Promise 对象。
上面代码中,await命令后面是一个Sleep对象的实例。这个实例不是 Promise 对象,但是因为定义了then方法,await会将其视为Promise处理。
下面这个例子演示了如何实现休眠效果。JavaScript 一直没有休眠的语法,但是借助await命令就可以让程序停顿指定的时间。下面给出了一个简化的sleep实现。
await命令后面的 Promise 对象如果变为reject状态,则reject的参数会被catch方法的回调函数接收到。
! 注意,上面代码中,await语句前面没有return,但是reject方法的参数依然传入了catch方法的回调函数。这里如果在await前面加上return,效果是一样的。但是如果resolve时必须要有return。! 注意!任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。
4. 异常处理
如果任意一个await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject。 为了防止此类情况发生,可以使用try...catch做异常处理
如果有多个await命令,可以统一放在try...catch结构中;或者根据实际情况进行分组异常处理。四、应用案例
1.租赁业务后台系统多次消息弹层
场景描述:检索用户,若用户已借绘本大于5本,押金小于100元则依次弹出提醒弹窗(需用户手动点击才可关闭弹窗)
上图为代码实现
2.小马吉米小程序登录
场景描述:输入手机号,获取验证码,校验手机是否登录,登录系统
未优化版本
优化版本
五、async 函数的实现原理
async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。
所有的async函数都可以写成上面的第二种形式,其中的spawn函数就是自动执行器