码迷,mamicode.com
首页 > 其他好文 > 详细

generator详解

时间:2017-10-22 11:10:17      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:ack   手动   user   col   函数   else   ring   封装   res   

generator函数

yield可以返回值,也可以传入值

形式:

注意!generator不能写成arrow function的形式!!!

function *函数(){
    代码1...

    let a = yield b; //b可以返回去给c

    代码2...
}
let Obj
=函数();

let c = Obj.next();
//执行代码1
genObj.next(5); //执行代码2 这里的5可以传入给a

 generator是一个异步串行的神器!!!

最传统的异步串行在前面的文章也介绍过,就是不断的嵌套回调函数,非常恶心。

用promise来写异步串行也是如此!!promise更适用与“异步并行”,即等齐所有异步结果再执行代码。

而今天的主角generator就很强势,直接可以把异步写成同步的写法~~

function *函数(){
    代码1...

    let a = yield b; //b假设是一个promise
    
    if(a == ‘~~~‘){
       let c = yield d; //d假设是一个promise
    }else{
        let e = yield f;//f假设是一个promise
    }
    代码2...
}

let g = 函数();

//h1接收第一个promise let h1
= g.next().value; let h2; //promise异步得到的数据传回给上面的a,把下一个promise传给h2 h1.then(res=>{h2 = g.next(res).value},err=>console.log(err)); h2.then(res=>g.next(res),err=>console.log(err));

当然上面这样写不太简洁,后面还要自己手动去next,把promise的结果传回去

我们可以考虑自己封装一个函数,采用递归的方式来自动实现下面的“next”的书写

runner

//这个runner是个函数,参数是一个generator函数
function runner(_gen){
  return new Promise((resolve, reject)=>{
    var gen=_gen();

    _next();
    //runner函数里面封装一个_next()函数用于递归
    function _next(_last_res){
      //首先res获取next得到的yield的返回值
      var res=gen.next(_last_res);
      //如果generator没有走完
      if(!res.done){
        var obj=res.value;
        //如果返回的是promise
        if(obj.then){
          //等promise返回数据 递归自己 next(res) 传入promise得到的数据
          obj.then((res)=>{
            _next(res);
          }, (err)=>{
            reject(err);
          });
        }
        //若返回的是generator
        else if(typeof obj==‘function‘){
          if(obj.constructor.toString().startsWith(‘function GeneratorFunction()‘)){
            runner(obj).then(res=>_next(res), reject);
          }
          //obj是一个普通函数,就会传这个函数return的值
          else{
            _next(obj());
          }
        }else{
          _next(obj);
        }
      }else{
        resolve(res.value);
      }
    }
  });
}
    

 

这样,以后写的代码就变得很简洁了!!

runner(function *(){
  let userData=yield $.ajax({url: ‘getUserData‘, dataType: ‘json‘});

  if(userData.type==‘VIP‘){
    let items=yield $.ajax({url: ‘getVIPItems‘, dataType: ‘json‘});
  }else{
    let items=yield $.ajax({url: ‘getItems‘, dataType: ‘json‘});
  }

  //生成、...
});

 

generator详解

标签:ack   手动   user   col   函数   else   ring   封装   res   

原文地址:http://www.cnblogs.com/amiezhang/p/7707523.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!