ES6 Generator函数的应用实例分析
本文实例讲述了ES6Generator函数的应用。分享给大家供大家参考,具体如下:
Generator函数是一种异步编程解决方案,Generator函数会返回一个遍历器对象,Generator函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式。
认识generator函数
function*fn(){
console.log('hello');
return'Joh';
}
//执行fn()时不会直接执行方法体中的代码,它会返回一个指针,这个指针实现了interator接口,也就是返回一个interator对象
letit=fn();
//通过调用next就会执行方法体,返回结果是{value:'Joh',done:true},其中next返回的是函数体中return的值
letres=it.next();
console.log(res);
generator函数中的yield与return
function*fn(){
//和yield相配合,把一个generator内部分为几个断点来执行,每个断点就是yield语句
//注意yield和return的区别:yield可以有多个,return只能有1个
yield1;
yield2;
yield3;
return4;//可以没有return值,done为true的value将会是undefined
}
letit=fn();
//在for-of循环中只能打印done为false的value值,done为true时,程序终止
for(letvofit){
console.log(v);//分别输出123
}
yield的值与赋值语句
function*fn(_name){
letname=yield_name;//yield的默认值为undefined
returnname;
}
letit=fn('Joh');
console.log(it.next());//{value:'Joh',done:false}
console.log(it.next('Tom'));//{value:'Tom',done:true}//此处value应该为undefined,但是通过next参数的形式赋值改变了最后一个值
console.log(it.next('Lily'));//{value:undefined,done:true}//已经循环完毕,即使传值也是undefined
yield语句的位置与括号
functionsum(a,b){
returna+b;
}
function*fn(){
letres=sum(yield1,5+(yield3));
console.log(res);
console.log('myqq:'+(yieldqq));//yield在一个语句中需要括起来
}
fn();
yield异常捕获
异常捕获的方式1:
function*fn(){
letqq=yield;//yield默认返回undefined,不会抛出异常
console.log(qq);
}
letg=fn();
g.next();//第一个断点没有输出
//g.next('qq11111');//完毕之后传值输出:qq11111
g.throw('error!');//Uncaughterror!
异常捕获的方式2:
function*fn(){
letqq;
try{
qq=yield;//yield默认返回undefined
}catch(e){
console.log('qqhaveerror');
}finally{
console.log(qq);
}
}
letg=fn();
g.next();
g.throw('error!');
//qqhaveerror
//undefined
异常捕获的方式3:
function*fn(){
letqq;
qq=yield;
console.log(qq);
}
letg=fn();
g.next();
try{
g.throw('error!');
}catch(e){
console.log('qqhaveerror!');
}
异常捕获的方式4:
function*fn(){
letqq;
try{
qq=yieldff;//ff未定义,所以qq不会被正确赋值此处是非yield的异常
}catch(e){
console.log('err1');
}
console.log(qq);
}
letg=fn();
g.next();
g.next('qq5554');
//err1
//undefined
利用generator和promise结合使用,让异步的逻辑关系,使用同步的方式书写
functionasyncF(name){
returnnewPromise(function(resolve){
setTimeout(function(){
resolve('mynameis'+name);
});
});
}
function*fn(){
console.log(yieldasyncF('Joh'));
}
letgf=fn();
functionexec(gf,value){
letres=gf.next(value);
if(!res.done){
if(res.valueinstanceofPromise){
res.value.then(function(v){
exec(gf,v);
})
}else{
exec(gf,res.value);
}
}
}
exec(gf);//mynameisJoh
更复杂的写法:
functionasyncF(name){
returnnewPromise(function(resolve){
setTimeout(function(){
resolve('mynameis'+name);
});
});
}
functionsum(a,b){
returnnewPromise(function(resolve){
setTimeout(function(){
resolve(a+b);
});
})
}
function*fn(name){
if((yieldsum(3,5))>6){
console.log(yieldasyncF(name));
}else{
console.log('error');
}
}
letgf=fn('Joh');
//generator执行器相当于tj/co模块
functionexec(gf,value){
letres=gf.next(value);
if(!res.done){
if(res.valueinstanceofPromise){
res.value.then(function(v){
exec(gf,v);
})
}else{
exec(gf,res.value);
}
}
}
exec(gf);//mynameisJoh
使用纯promise实现:
functionasyncF(name){
returnnewPromise(function(resolve){
setTimeout(function(){
resolve('mynameis'+name);
});
});
}
functionsum(a,b){
returnnewPromise(function(resolve){
setTimeout(function(){
resolve(a+b);
});
})
}
functionfn(name){
sum(3,5)
.then(function(num){
if(num>6){
asyncF(name)
.then(function(v){
console.log(v);
})
}else{
console.log('error');
}
})
}
fn('Joh');
使用co模块,来代替自己写的执行器
varco=require('co');
functionasyncF(name){
returnnewPromise(function(resolve){
setTimeout(function(){
resolve('mynameis'+name);
});
});
}
functionsum(a,b){
returnnewPromise(function(resolve){
setTimeout(function(){
resolve(a+b);
});
})
}
function*fn(name){
if((yieldsum(3,5))>6){
console.log(yieldasyncF(name));
}else{
console.log('error');
}
}
varfnx=co.wrap(fn);
fnx('Joh');//mynameisJoh
更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。