JavaScript之ES6中的生成器函数Generator
1、Generator定义
生成器函数Generator是一种异步编程的解决方案,比Promise更高级。
除了通过return 返回值之外,generator还可以通过yield多次返回值。
//function后紧跟* function* hello(){ yield ...; yield ...; ... };
2、常用API
generator实例通过 next() 方法一步一步执行yield,第1次next(),返回第1个yield和是否完毕的状态(true \false),第2次next(),返回第2个yield……,当全部返回值都访问后,状态才为true。
{ let tell = function*(){ yield 'a';//step1 yield 'b';//step2 return 'c'; } let k = tell();//generator实例化 console.log(k.next());// a false 执行第1个yield console.log(k.next());//b false 执行第2个yield console.log(k.next());//c true console.log(k.next());//undefined true }
generator实例可以通过for……of遍历。
{ //遍历器 let obj ={}; obj[Symbol.iterator] = function*(){ yield 1; yield 2; yield 3; } for(let key of obj){ console.log(key);//1 2 3 } }
3、用法
1、状态机
{ //状态机 let state = function*(){ while(1){ yield 'A'; yield 'B'; yield 'C'; } } let status = state(); console.log(status.next());//A console.log(status.next());//B console.log(status.next());//C console.log(status.next());//A console.log(status.next());//B }
2、抽奖
{ //抽奖逻辑,抽奖次数限制 let draw = function(count){ //具体抽奖逻辑 console.info(`剩余${count}次`); } let residue = function*(count){ while(count>0){ count --; yield draw(count); } } let start = residue(5);//实例化 let btn = document.createElement('button'); btn.id = 'start'; btn.textContent = '抽奖'; document.body.appendChild(btn); document.getElementById('start').addEventListener('click',function(){ start.next(); },false) }
3、长轮询
{ //定时获取服务端变化,长轮询 let ajax = function*(){ yield new Promise(function(resolve,reject){ setTimeout(function(){ resolve({code:0}); //resolve({code:1});//每隔1200ms输出一个wait },200); }) } let pull = function(){ let generator = ajax();//generator实例化 let step = generator.next();//next()方法 step.value.then(function(d){ //step.value即为Promise实例 if(d.code != 0){ setTimeout(function(){ console.log('wait'); pull(); },1000) }else{ console.info(d);//code 0 } }) } pull(); }