1.Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同。
Generator函数有两个特征。一是,function
关键字与函数名之间有一个星号;二是,函数体内部使用yield
语句,定义不同的内部状态。
1 { 2 // Generator函数 * , yield 3 let tell = function* (){ 4 yield 'a'; 5 yield 'b'; 6 return 'c'; 7 }; 8 let say = tell(); 9 console.log(say.next()); //输出结果与iterator类似,实际上是实现了Symbol.iterator接口 10 console.log(say.next()); 11 console.log(say.next()); 12 console.log(say.next()); 13 }
2,使用Generator实现对象遍历
1 { 2 let obj = {}; 3 obj[Symbol.iterator] = function* (){ 4 yield 1; 5 yield 2; 6 yield 3; 7 } 8 for(var value of obj){ 9 console.log("value",value) 10 } 11 }
3,状态机实现循环
1 { 2 let state= function* (){ 3 while(1){ 4 yield 'a'; 5 yield 'b'; 6 yield 'c'; 7 } 8 } 9 let status = state(); 10 console.log(status.next()) //"a" 11 console.log(status.next()) //"b" 12 console.log(status.next()) //"c" 13 console.log(status.next()) //"a" 14 console.log(status.next()) //"b" 15 }
4.例子:a.实现抽奖环节
1 { 2 // 实例实现抽奖环节 3 let draw =function(count){ 4 // 具体抽奖逻辑 5 console.info('剩余抽奖次数:',count) 6 } 7 //次数限制 8 let rest= function* (count){ 9 while(count>0){ 10 count--; 11 yield draw(count); 12 } 13 } 14 let start = rest(5); //次数由服务器端传给前端 15 16 let btn = document.createElement("button"); 17 btn.id="startButton"; 18 btn.textContent="抽奖"; 19 document.body.appendChild(btn); 20 document.getElementById("startButton").addEventListener('click',function(){ 21 start.next(); 22 },false); 23 24 }
b.定时获取服务器端数据
1 { 2 // 定时取服务器端的数据 1.websocket(浏览器兼容性不好) 2.长轮询 3 // 长轮询 4 let ajax = function* (){ 5 yield new Promise(function(resolve,reject){ 6 setTimeout(()=>{ //模拟服务器返回值和响应时间 7 resolve({code:0}) 8 },1000) 9 }); 10 } 11 let pull = function(){ 12 let generator = ajax(); 13 let step = generator.next(); //返回值是promise对象,可以调用then方法进行回调 14 step.value.then(function(d){ 15 if(d.code != 0){ 16 console.info("await") 17 pull(); 18 }else{ 19 console.info(d) 20 } 21 }) 22 } 23 pull() 24 }