• ES6学习之Generator函数


    概念:可以把Generator 函数理解成状态机(封装了多个内部状态)或者是一个遍历器对象生成函数

    写法:Generator函数的定义跟普通函数差不多,只是在function关键字后面加了一个星号

    function* test(){
      yield 'hello';
      yield 'world';
      return 'done'
    }
    
    var te = test(); //什么都没有
    te.next(); //{ value: 'hello', done: false }
    te.next(); //{ value: 'world', done: false }
    te.next(); //{ value: 'done', done: true }
    te.next(); //{ value: undefined, done: true }

    说明:1)不管内部有没有yield语句,调用Generator函数,该函数并不立即执行,也不返回函数执行结果,而是返回一个指向内部状态的generator对象,也可以看作是一个遍历器对象。

              2)必须调用该对象的next方法,让函数继续走下去,使指针移向下一个状态。每当碰到yield语句,内部指针就停下来,直到下一次调用next()才开始执行。

              3)如果没有再遇到yield 则返回return的值为value的属性值

              4)如果没有return表达式,则将undefined作为value的属性值

              5)Generator函数中可以没有yield表达式,此时,Generator函数表示一个暂缓执行函数

    Generator函数的next()方法:(next方法内可以传入参数,传入的参数将作为上一个yield表达式的返回值(意思是第一个next传入参数无效))

    function* gen(a) {
        let b = yield (a + 1);
        return b * 2;
    }
    let g = gen(1);
    g.next();  //  Object {value: 2, done: false}
    g.next();  //  Object {value: NaN, done: true}
    let ge = gen(1);
    ge.next();  //  Object {value: 2, done: false}
    ge.next(3);  //  Object {value: 6, done: true}

    上面第二次调用g.next()返回的value为NaN而不是2*2,说明yield表达式没有返回值,或者说yield表达式总是返回undefined

    for...of遍历Generator函数内的状态

    function *foo() {
      yield 1;
      yield 2;
      yield 3;
      yield 4;
      yield 5;
      return 6;
    }
    
    for (let v of foo()) {
      console.log(v);
    }
    // 1 2 3 4 5

    return语句不会被遍历

    yield* 表达式(用来在一个 Generator 函数里面执行另一个 Generator 函数。)

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

    Generator函数的异步编程

    • 异步函数的同步实现
    function* loadUI() {
      showLoadingScreen();
      yield loadUIDataAsynchronously();
      hideLoadingScreen();
    }
    var loader = loadUI(); //这一步什么都不执行
    loader.next()  //执行函数showLoadingScreen()和loadUIDataAsynchronously()
    loader.next()  //执行函数hideLoadingScreen
    • 流程控制
    function* execute() {
        let value1;
        let value2;
        let value3;
        let value4;
        yield value1 = step1();
        yield value2 = step2(value1);
        yield value3 = step3(value2);
        yield value4 = step4(value3);
        console.log(value4);
    }
    function step1() {
        return `step1_start`;
    }
    function step2(value) {
        return `step2_${value}`;
    }
    function step3(value) {
        return `step3_${value}`;
    }
    function step4(value) {
        return `step4_${value}`;
    }
    
    for(var item of execute());  //step4_step3_step2_step1_start

    注意:yield总是返回undefined,但此处并不是直接返回yiled,而是给yield后面的变量赋值,故能运算

  • 相关阅读:
    二进制数组ArrayBuffer
    iperf3测量一个网络最大带宽
    Proxy与Reflect
    Symbol
    Iterator
    Set与Map
    Generator
    Android 共享参数 SharedPreferences
    DDMS files not found: xxxhprof-conv.exe
    Android 状态栏通知 Notification
  • 原文地址:https://www.cnblogs.com/sghy/p/7976491.html
Copyright © 2020-2023  润新知