• generator详解


    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'});
      }
    
      //生成、...
    });
  • 相关阅读:
    mac本地如何搭建IPv6环境测试你的APP
    消息通知机制(NSNotification和NSNotificationCenter)
    Xcode 6制作动态及静态Framework
    html格式化输出JSON( 测试接口)
    UIContainerView纯代码实现及原理介绍
    CocoaPods 详解之----更新篇
    使用Cocoapods创建私有podspec
    ios高效开发-正确的使用枚举(Enum)
    在Xcode6中搭建Python开发环境
    用Swift语言做App开发之单元测试
  • 原文地址:https://www.cnblogs.com/amiezhang/p/7707523.html
Copyright © 2020-2023  润新知