zoukankan      html  css  js  c++  java
  • es6generator

    yield语句

    由于Generator函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield语句就是暂停标志。

    yield语句只能用在 Generator 函数里面,用在其他地方都会报错。

    yield语句如果用在一个表达式之中,必须放在圆括号里面。yield语句用作函数参数或放在赋值表达式的右边,可以不加括号。

    function* demo() {
      console.log('Hello' + yield); // SyntaxError
      console.log('Hello' + yield 123); // SyntaxError
    
      console.log('Hello' + (yield)); // OK
      console.log('Hello' + (yield 123)); // OK
    }
    function* demo() {
      foo(yield 'a', yield 'b'); // OK
      let input = yield; // OK
    }

      

    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 }
    

      

    for...of循环

    for...of循环可以自动遍历Generator函数时生成的Iterator对象,且此时不再需要调用next方法。

    一旦next方法的返回对象的done属性为truefor...of循环就会中止,且不包含该返回对象。

    除了for...of循环以外,扩展运算符(...)、解构赋值和Array.from方法内部调用的,都是遍历器接口。

    function* numbers () {
      yield 1
      yield 2
      return 3
      yield 4
    }
    
    // 扩展运算符
    [...numbers()] // [1, 2]
    
    // Array.from 方法
    Array.from(numbers()) // [1, 2]
    
    // 解构赋值
    let [x, y] = numbers();
    x // 1
    y // 2
    
    // for...of 循环
    for (let n of numbers()) {
      console.log(n)
    }
    // 1
    // 2
    

      

    Generator.prototype.return()

    Generator函数返回的遍历器对象,还有一个return方法,可以返回给定的值,并且终结遍历Generator函数。

    function* gen() {
      yield 1;
      yield 2;
      yield 3;
    }
    
    var g = gen();
    
    g.next()        // { value: 1, done: false }
    g.return('foo') // { value: "foo", done: true }
    g.next()        // { value: undefined, done: true }
    

      如果Generator函数内部有try...finally代码块,那么return方法会推迟到finally代码块执行完再执行。

    这意味着,它们都可以将Generator函数返回的Iterator对象,作为参数。

    function* numbers () {
      yield 1;
      try {
        yield 2;
        yield 3;
      } finally {
        yield 4;
        yield 5;
      }
      yield 6;
    }
    var g = numbers()
    g.next() // { done: false, value: 1 }
    g.next() // { done: false, value: 2 }
    g.return(7) // { done: false, value: 4 }
    g.next() // { done: false, value: 5 }
    g.next() // { done: true, value: 7 }
    

      

    yield* 语句 

    在 Generator 函数内部,调用另一个 Generator 函数。

    function* bar() {
      yield 'x';
      yield* foo();
      yield 'y';
    }
    
    // 等同于
    function* bar() {
      yield 'x';
      yield 'a';
      yield 'b';
      yield 'y';
    }
    
    // 等同于
    function* bar() {
      yield 'x';
      for (let v of foo()) {
        yield v;
      }
      yield 'y';
    }
    
    for (let v of bar()){
      console.log(v);
    }
    // "x"
    // "a"
    // "b"
    // "y"
    

      任何数据结构只要有Iterator接口,就可以被yield*遍历。

    应用 

    (1)异步操作的同步化表达 

    (2)控制流管理 

    (3)部署Iterator接口 

    利用Generator函数,可以在任意对象上部署Iterator接口。

    function* iterEntries(obj) {
      let keys = Object.keys(obj);
      for (let i=0; i < keys.length; i++) {
        let key = keys[i];
        yield [key, obj[key]];
      }
    }
    
    let myObj = { foo: 3, bar: 7 };
    
    for (let [key, value] of iterEntries(myObj)) {
      console.log(key, value);
    }
    
    // foo 3
    // bar 7

     对数组部署Iterator接口

    function* makeSimpleGenerator(array){
      var nextIndex = 0;
    
      while(nextIndex < array.length){
        yield array[nextIndex++];
      }
    }
    
    var gen = makeSimpleGenerator(['yo', 'ya']);
    
    gen.next().value // 'yo'
    gen.next().value // 'ya'
    gen.next().done  // true
    

      

    (4)作为数据结构 

  • 相关阅读:
    LINUX下用select实现串口通讯示例
    续——老机焕发青春——win8 ramos 的本地安装 (涉及vhd差分盘)
    nexus 4 下 ubuntu touch 配置 nodejs环境
    nexus 4 下 DualBootInstallation 安装 ubuntu touch
    老机焕发青春 之硬盘篇
    Mac 10.9.2后airplay出现的bug
    初识javascript(一):js在windows下运行的几种形式
    过了一年了.关于扁平化.和一些唠叨
    inet_ntop(), inet_pton() inet_ntoa(), inet_aton(), inet_addr, htons(), htonl(), ntohs(), ntohl() struct hostent ,struct sockaddr_in
    gethostbyname尽量少用
  • 原文地址:https://www.cnblogs.com/detanx/p/es6generator.html
Copyright © 2011-2022 走看看