首页 > 网页制作  > 前端开发

进阶学习7:JavaScript异步编程——Generator异步方案、Async/ Await

admin 前端开发 2021-05-25 09:28:58
后台-系统设置-扩展变量-手机广告位-内容正文底部

目录

六、Generator异步方案

1.前言

2.了解Generator的特点和基本使用

 3.使用Generator去实现异步

4.Async / Await语法糖


六、Generator异步方案

1.前言

前面学习到的链式调用Promise呢还是和我们同步模式不太一样,我们希望能够代码更加扁平化,而ES2015中提供的Generator就能解决这个问题

2.了解Generator的特点和基本使用

想解释的都写在下面代码的注释里拉。

//DEMO9
// 生成器函数回顾
// 比普通函数多了一个*号
function * foo () {
    console.log('start')
    try{
        const res = yield 'foo' // 函数内部可以随时使用yield返回一个值
        console.log(res)
    }
    catch (e) {
        console.log(e)
    }
    
}
const generator = foo()//不会立即执行函数,而是返回了一个Generator对象
console.log(generator)

const result = generator.next()//调用next()的时候才执行
//可以在接受.next()对象返回值这拿到yield返回的值,看console的结果里面还有一个done属性代表生成器是否全部执行完了
//yield不像return直接结束函数执行,只是暂停生成器执行
console.log(result)
//再次调用生成器.next()会从yield往后执行,给.next()中添加值的话,能让生成器函数yield获得一个接收值,也就是样例中res
const result2 = generator.next('bar')
console.log(result2)

//这里需要把上面两行注释掉,假如不注释的话生成器函数就已经结束了,生成器那是不会catch到Error的
generator.throw(new Error('Generator Error'))

结果:

注释掉这两行代码之后,再跑一次

const result2 = generator.next('bar')
console.log(result2)

结果:

 3.使用Generator去实现异步

//DEMO9
// 生成器函数 配合 Promise的异步方案
function * main () {
    try {
      const users = yield ajax('/api/users.json')
      console.log(users)
  
      const posts = yield ajax('/api/posts.json')
      console.log(posts)
  
      const urls = yield ajax('/api/urls.json')
      console.log(urls)
    } catch (e) {
      console.log(e)
    }
}

const g = main()
const result = g.next()
console.log(result.value)//返回的是promise
result.value.then(data => {
    const result2 = g.next(data)
    if(result2.done) return
    result2.value.then(data => {
        const result3 = g.next(data)
        if(result3.done) return
        result3.value.then(data =>
            g.next(data))
    })
})

结果:

这样确实是完成了我们想要做的,但是一层层的,代码实在是太丑了,完全可以使用递归来完成,下面就改造成递归,再增加异常捕获

function * main () {
    try {
      const users = yield ajax('/api/users.json')
      console.log(users)
      const posts = yield ajax('/api/posts.json')
      console.log(posts)
      const urls = yield ajax('/api/urls.json')
      console.log(urls)
      const urls_error = yield ajax('/api/urls111.json')
      console.log(urls_error)
    } catch (e) {
      console.log(e)
    }
}

const g = main()
function handleResut(result) {
    if(!result.done){
        result.value.then(data => {
            const result2 = g.next(data)
            return handleResut(result2)
        }, error => {
            g.throw(error)
        })
    }else{
        return
    }
}

handleResut(g.next())

看一下运行结果,改造成功

4.Async / Await语法糖

ES2017中新增的,是语言层面的异步编程标准,使用起来更加方便一些(确实这个也是我自己在工作中使用最多的,实在是太方便了,代码阅读起来也容易)

//DEMO10
//ASYNC AWAIT
async function main () {
    try {
      const users = await ajax('/api/users.json')
      console.log(users)
  
      const posts = await ajax('/api/posts.json')
      console.log(posts)
  
      const urls = await ajax('/api/urls.json')
      console.log(urls)
    } catch (e) {
      console.log(e)
    }
}
  
const promise = main()
  
promise.then(() => {
    console.log('all completed')
})

返回结果: 

文章来源:https://blog.csdn.net/qq_43106115/article/details/117201178

后台-系统设置-扩展变量-手机广告位-内容正文底部
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。
本文地址:https://www.jcdi.cn/qianduankaifa/30878.html

留言与评论(共有 0 条评论)
   
验证码:
后台-系统设置-扩展变量-手机广告位-评论底部广告位

教程弟

https://www.jcdi.cn/

统计代码 | 京ICP1234567-2号

Powered By 教程弟 教程弟

使用手机软件扫描微信二维码