zoukankan      html  css  js  c++  java
  • es6之Generator

    Generator 函数是 ES6 提供的一种异步编程解决方案.

    执行 Generator 函数会返回一个遍历器对象

    Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)

    {
      // genertaor基本定义
      let tell=function* (){
        yield 'a';
        yield 'b';
        return 'c'
      };
    
      let k=tell();
    
      console.log(k.next());
      console.log(k.next());
      console.log(k.next());
      console.log(k.next());
    }
    //{value: "a", done: false}
    // {value: "b", done: false}
    // {value: "c", done: true}
    // {value: undefined, done: true}

    调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象。

    下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。

    与 Iterator 接口的关系

    任意一个对象的Symbol.iterator方法,等于该对象的遍历器生成函数,调用该函数会返回该对象的一个遍历器对象。

    由于 Generator 函数就是遍历器生成函数,因此可以把 Generator 赋值给对象的Symbol.iterator属性,从而使得该对象具有 Iterator 接口。

    {
      let obj={};
      obj[Symbol.iterator]=function* (){
        yield 1;
        yield 2;
        yield 3;
      }
    
      for(let value of obj){
        console.log(value);
      }
    }
    //1
    //2
    //3

    next 方法的参数

    yield表达式本身没有返回值,或者说总是返回undefinednext方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。

    function* foo(x) {
      var y = 2 * (yield (x + 1));
      var z = yield (y / 3);
      return (x + y + z);
    }
    
    var a = foo(5);
    a.next() // Object{value:6, done:false}
    a.next() // Object{value:NaN, done:false}
    a.next() // Object{value:NaN, done:true}
    
    var b = foo(5);
    b.next() // { value:6, done:false }
    b.next(12) // { value:8, done:false }
    b.next(13) // { value:42, done:true }

    上面代码中,第二次运行next方法的时候不带参数,导致 y 的值等于2 * undefined(即NaN),除以 3 以后还是NaN,因此返回对象的value属性也等于NaN。第三次运行Next方法的时候不带参数,所以z等于undefined,返回对象的value属性等于5 + NaN + undefined,即NaN

    如果向next方法提供参数,返回结果就完全不一样了。上面代码第一次调用bnext方法时,返回x+1的值6;第二次调用next方法,将上一次yield表达式的值设为12,因此y等于24,返回y / 3的值8;第三次调用next方法,将上一次yield表达式的值设为13,因此z等于13,这时x等于5y等于24,所以return语句的值等于42

    注意,由于next方法的参数表示上一个yield表达式的返回值,所以在第一次使用next方法时,传递参数是无效的。

    在抽奖逻辑显示上的应用

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
    </head>
    <body>
      <script type="text/javascript">
      {
      let draw=function(count){
        //具体抽奖逻辑
        console.info(`剩余${count}次`)
      }
    
      let residue=function* (count){
        while (count>0) {
          count--;
          yield draw(count);
        }
      }
    
      let star=residue(5);
      let btn=document.createElement('button');
      btn.id='start';
      btn.textContent='抽奖';
      document.body.appendChild(btn);
      document.getElementById('start').addEventListener('click',function(){
        star.next();
      },false)
    }
      </script>
    </body>
    </html>

    与Promise结合的应用

    {
      // 长轮询
      let ajax=function* (){
        yield new Promise(function(resolve,reject){
          setTimeout(function () {
            resolve({code:0})
           //resolve({code:1})
          }, 200);
        })
      }
    
      let pull=function(){
        let generator=ajax();
        let step=generator.next();
        step.value.then(function(d){
          if(d.code!=0){
            setTimeout(function () {
              console.info('wait');
              pull()
            }, 1000);
          }else{
            console.info(d);
          }
        })
      }
    
      pull();
    }
  • 相关阅读:
    springboot雷神更新
    JVM整理文档
    这是我见过BIO/NIO/AIO讲的最清楚的博客了
    redis主从机制
    mybatis是如何防止sql注入的
    分布式锁的实现方式简介
    Nginx简介
    .net 下的集合
    C#模拟百度登录
    WPF 将PPT,Word转成图片
  • 原文地址:https://www.cnblogs.com/sunmarvell/p/9149540.html
Copyright © 2011-2022 走看看