一、Generator定義ajax
生成器函數Generator是一種異步編程的解決方案,比Promise更高級。編程
除了經過return 返回值以外,generator還能夠經過yield屢次返回值。app
//function後緊跟* function* hello(){ yield ...; yield ...; ... };
二、經常使用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 } }
三、用法spa
一、狀態機code
{ //狀態機 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 }
二、抽獎blog
{ //抽獎邏輯,抽獎次數限制 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) }
三、長輪詢get
{ //定時獲取服務端變化,長輪詢 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(); }