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程序设计有所帮助。