async是generator的语法糖,async=Generator+co(自动执行器)
了解其原理首先得来看看generator。
node=>express=>koa=>koa2其实就是回调=>promise=>generator=>async
从上述演变中看出generator也是处理回调的一种方式。
Generator
示例:
var a=1;
function *fun(){
a++;
yield 'xixihaha'
a++;
console.log('edm')
}
var obj=fun();
控制台发现什么也没打印,其实这里的生成器*foo()没有像普通函数一样运行,它只是创建了一个迭代器。
需要通过.next()手动控制向下执行。
console.log(obj.next());
console.log(a);
console.log(obj.next());
console.log(a);
可以看到obj.next()返回了一个对象,对象的value值就是当前yield的值,
第二次next后顺利打印除了edm同时done置为true。
这样能让你的代码按照想要顺序分段执行,但要自己手动控制。
自动执行器
那有什么办法让它自动执行吗,我们发现可以对返回的对象的done属性进行判断,递归执行即可。
function autofun(target){
var res=target.next();
if(!res.done){
autofun(target)
}
}
异步结果还没出来就被执行了,所以进行下修改支持异步:
function autofun(target){
var res=target.next();//res.value是个promise对象
if(!res.done){
res.value.then(()=>{
autofun(target)
})
}
}
接下来写段代码测试
//模拟异步的代码块
function axiosmeth(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('3');
console.log('3');
},0)
})
}
//形似async的代码块
function *fun(){
console.log('1');
yield axiosmeth();
console.log('4');
}
//自动执行函数代码块
function autofun(target){
var res=target.next();//res.value是个promise对象
if(!res.done){
res.value.then(()=>{
autofun(target)
})
}
}
autofun(fun())
console.log('2')
先执行autofun函数打印1,由于函数中存在异步操作于是先打印了函数外的2,
紧接着执行异步函数打印3,异步函数执行完毕最后打印4。