每天十分钟学好ES6--async和Generator是一对好基友

Posted 桃子叔叔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每天十分钟学好ES6--async和Generator是一对好基友相关的知识,希望对你有一定的参考价值。

async 函数是ES7标准引入的

一、什么是async函数

1、async 让异步代码变得像同步代码一样

  • 返回一个promise对象
  • promise对象的结果由async函数执行结果的返回值决定

2、Generator 的好基友(语法糖)

虽然说async函数是Generator函数的好基友,但是一点也不省油,首先让我们看一下它们的区别

2.1 好基友的不同点

通过下面两段代码可以发现,async函数就是将Generator函数的星号*替换成async,将yield替换成await

// Generator函数:
function * gen()
	let users = yield getUsers()
	let orders = yield getOrders()
	let goods = yield getGoods()


let iterator = gen()
iterator.next()

Generator函数标志是星号*和yield,通过next()来一步步执行yield操作。

可以说Generator函数是被动型,不喜欢自己动,喜欢被步步紧逼。
但是async函数就是主动型选手了。

const p = new Promise((resolve, reject)=> 
    resolve('用户数据')
)

var main = async function () 
    try 
        let result = await p;
        console.log(result) // 用户数据
     catch (error) 
        console.log(e)
       
    // 通过try...catch捕获reject的返回值

main()

async函数自带执行器,一次调用,自动输出,这也是大家更喜欢async函数的原因。

2.2 async函数对好基友Generator进行了改进
  1. 第一个就是前面说的,async是主动的,自带执行器,而Generator喜欢被动,除非搭配co模块
  2. async语义更好,async表示有异步操作,await表示屁股后面紧跟的表达式需要结果
  3. async适用性更广,可谓人见人爱
  4. async返回值是Promise对象,可用then指定下一步操作,用起来很方便

一句话总结,async函数主动型、人见人爱、好用,接下来就详细说一下async的用法。

二、async函数用法

1、async基本语法

async function fn() 
// 如果函数返回的结果不是promise对象,async返回的结果就是成功的promise对象
// 如果函数返回的结果是一个promise对象,则根据函数内promise的结果判断
// 例如下面的promise函数
    return new Promise((resolve, reject)=> 
        resolve('成功的数据')
        // reject('失败的数据')
    )

const result = fn()

result.then((value)=> 
    console.log(value) // '成功的数据' 如果函数体内的promise返回resolve则走这里
, (reason)=> 
    console.log(reason)// '失败的数据' 如果函数体内的promise返回reject则走这里
)

2、await语法

2.1 await必须写在async函数中
2.2 await右侧的表达式一般为promise对象
2.3 await返回的是promise成功的值
2.4 await的promise失败了,就会抛出异常,需要通过try…catch捕获异常
const p = new Promise((resolve, reject)=> 
    resolve('用户数据')
)

async function main() 
    try 
        let result = await p;
        console.log(result) // 用户数据
     catch (error) 
        console.log(e)
       
    // 通过try...catch捕获reject的返回值


2.5 async返回的Promise对象必须等到内部所有await命令后的Promise对象执行完才发生状态改变,即执行then方法指定的回调函数,除非遇到return或抛出错误。
2.6 只要一个await语句后面的promise变成reject,那个整个async函数都会中断执行
async function f() 
    await Promise.reject('出错了')
    await Promise.resolve('这里不会执行')

上面代码中的第二行不会执行,因为第一个await语句状态变成了reject。

有时我们希望前一个promise中断不影响后面的await语句执行,这时需要将await放在try…catch语句中

async function f() 
    try 
        await Promise.reject('出错了')
     catch (error) 
    await Promise.resolve('这里不会执行')

另一种方法是将前面的await语句加上catch方法,处理前面可能出现的错误。

async function f() 
    await 
    Promise.reject('出错了')
    .catch(e=> console.log(e))
    await Promise.resolve('这里不会执行')

3、await实际应用

如果我们有三个登录权限需要去判断,只要命中其中一个就可以退出判断,不再进行其他判断,使用Promise和async实现:

let a = new Promise((resolve, reject)=>
    let status = true
    // a权限逻辑判断代码----
    if (status) 
        resolve(status)
     else 
        reject(status)
    
)

let b = new Promise((resolve, reject)=>
    let status = true
    // b权限逻辑判断代码----
    if (status) 
        resolve(status)
     else 
        reject(status)
    
)

let c = new Promise((resolve, reject)=>
    let status = true
    // c权限逻辑判断代码----
    if (status) 
        resolve(status)
     else 
        reject(status)
    
)

let authList = [a, b, c]
let test = async function()
    for(let auth of authList)
        try 
			await auth
            break
		 catch (error) 
			console.log(error)
		
    

在上面async代码中,如果await操作成功,则会使用break语句退出循环;如果失败,则会被catch语句捕捉,然后进入下一轮循环。

以上是关于每天十分钟学好ES6--async和Generator是一对好基友的主要内容,如果未能解决你的问题,请参考以下文章

每天十分钟学好ES6---新集合Set和Map

每天十分钟学好ES6---新集合Set和Map

每天十分钟学好ES6---新集合Set和Map

每天十分钟学好ES6---新集合Set和Map

每天十分钟学好ES6--掌握Promise就是这么简单

每天十分钟学好ES6--掌握Promise就是这么简单