async函数
在ES2017中引入了async
函数,使用该关键词可以说明该函数是一个异步函数,再配合await
即可轻松实现异步执行的效果。
例如从指定的url地址上获取数据将数据返回,使用async
如下
async function getData(url) {
const data = await fetch(url)
return data.text;
}
看起来实现方式和Generator很像,使用Generator方式
const co = require('co')
function* getData(url) {
const data = yield fetch(url)
return data.text
}
co(getData)
这里借助了co
模块,这是一个Generator的运行器。可以看到,async
的写法和Generator的写法很相似,其实async
就是Generator的语法糖,只不过,Generator运行需要借助于运行器,async
其实是使用的内置的运行器,这样会更加的方便。
运行器的实现思路就是将Generator包装在一个Promise函数中,不断迭代Generator的next
,直到执行结束resolve
,如果执行中出现错误直接reject
出去,具体实现代码如下:
//该代码借鉴自阮一峰的《ECMAScript 6入门》
//http://es6.ruanyifeng.com/#docs/async#async-%E5%87%BD%E6%95%B0%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86
function spawn(genF) {
return new Promise((resolve, reject) => {
let gen = genF();
function step(nextF) {
let next;
try {
next = nextF()
} catch (e) {
//执行异常,reject这个Promise
return reject(e)
}
//迭代结束时,resolve这个Promise
if (next.done) {
return resolve(next.value)
}
Promise.resolve(next.value).then(
//递归next(),并将当前的value传递给下一个
v => step(() => gen.next(v)),
e => step(() => gen.throw(e))
);
}
//初始迭代
step(() => gen.next(undefined))
})
}
调用方式如下
function testDelayFunc() {
return new Promise(resolve => {
setTimeout(() => {
resolve('hello world')
}, 500)
})
}
function* testGenerator() {
const a = yield testDelayFunc()
const b = yield 'good boy'
console.log(a, b);
}
spawn(testGenerator); //hello world good boy
如果您觉得本文对您有用,欢迎捐赠或留言~
- 本博客所有文章除特别声明外,均可转载和分享,转载请注明出处!
- 本文地址:https://www.leevii.com/?p=1083