zoukankan      html  css  js  c++  java
  • 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'});
      }
    
      //生成、...
    });
  • 相关阅读:
    intel 1211网卡驱动
    winform 右侧关闭按钮事件
    base64 教程
    js 预览图片 转base64
    docker常用命令
    docker安装
    jenkins集成sonar
    jenkins自动打包部署linux
    mac生成ssh公私匙
    jenkins统计单元测试的覆盖率
  • 原文地址:https://www.cnblogs.com/amiezhang/p/7707523.html
Copyright © 2011-2022 走看看