进阶学习7:JavaScript异步编程——Generator异步方案Async/ Await
Posted JIZQAQ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进阶学习7:JavaScript异步编程——Generator异步方案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')
})
返回结果:
以上是关于进阶学习7:JavaScript异步编程——Generator异步方案Async/ Await的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript学习--Item27 异步编程异常解决方案