美文网首页
ES6之generator

ES6之generator

作者: sarah_wqq | 来源:发表于2019-02-01 15:20 被阅读0次

    概念

    Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
    Generator 有两个特征:

    • function关键字与函数名之间有一个星号
    • 函数体内部使用yield表达式,定义不同的内部状态。
    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    var hw = helloWorldGenerator();
    

    helloWorldGenerator函数有三个状态:hello,world 和 return 语句(结束执行)。
    调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针遍历器对象(Iterator Object)。

    下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。
    Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。

    hw.next()
    // { value: 'hello', done: false }
    
    hw.next()
    // { value: 'world', done: false }
    
    hw.next()
    // { value: 'ending', done: true }
    
    hw.next()
    // { value: undefined, done: true }  Generator 已经执行完毕,以后再调用next方法,返回的都是这个值
    

    另一个例子:

    function* f() {
      console.log('执行了!')
    }
    var generator = f(); //f是Generator 函数,在这里不会执行
    setTimeout(function () {
      generator.next() //只有调用了next才会执行,打印“执行了”
    }, 2000);
    

    next方法

    yield表达式本身没有返回值,或者说总是返回undefined。
    next方法可以带一个参数,该参数就会被当作上一个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),返回对象的value属性等于y / 3即NaN。第三次运行Next方法的时候不带参数,所以z等于undefined,返回对象的value属性等于5 + NaN + undefined,即NaN。

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

    注意,由于next方法的参数表示上一个yield表达式的返回值,所以在第一次使用next方法时,传递参数是无效的。V8 引擎直接忽略第一次使用next方法时的参数,只有从第二次使用next方法开始,参数才是有效的。从语义上讲,第一个next方法用来启动遍历器对象,所以不用带有参数。

    相关文章

      网友评论

          本文标题:ES6之generator

          本文链接:https://www.haomeiwen.com/subject/rbrdsqtx.html