• es6之Generator


    1.Generator函数其实是一个封装了多个内部状态的状态机,执行它会返回一个遍历器对象,然后可以依次遍历Generator中的每一个状态,也就是分段执行,yield是暂停执行的标记,next恢复执行。

    2.yield:

      - 一个函数里面,return只能执行一遍,yield可以执行多次;

      - Generator函数可以不用yield,这时就是一个简单的暂缓执行函数;

      - yield只能用在Generator函数里;

      - yield如果用在一个表达式里,必须放在圆括号里

    function* foo() {
        console.log('hello' + (yield));
        console.log('hello' + (yield 'world'));
    }

      - yield用于函数参数或放在赋值表达式的右边,可以不加括号

    function* demo() {
        foo(yield 'a', yield 'b');
        let input = yield;
    }

     3.可以把Generator函数赋值给对象的Symbol.iterator属性,从而使对象具有Iterator接口

    var obj = {};
    obj[Symbol.iterator] = function* (){
        yield 1;
        yield 2;
    };
    
    [...obj] // [1,2]

    4.next方法的参数会被当做上一个yield的返回值,这样就可以在函数运行期间向内部传值。

    5.for...of会自动遍历Generator函数生成的Iterator对象,不需要调用next方法。

    // 实现Fibonacci数列
    function* fib() {
        let [prev, curr] = [0, 1];
        for (;;) {
            [prev, curr] = [curr, prev + curr];
            yield curr;
        }
    }
    
    for (let n of fib()) {
        if (n > 1000) break;
        console.log(n);
    }

    6.遍历器对象的throw方法。

    7.遍历器对象的return方法可以返回给定的值且终结遍历。

    8.yield* 表达式用来在一个Generator函数里调用另一个Generator函数,而后面这个函数其实就是for...of的一种简写;

      - yield* 后面如果跟着数组,则会遍历该数组;

      - yield* 后面如果跟着字符串,也会遍历字符串;

      - 如果后面的Generator函数有return语句,那么就可以像这个函数返回数据

    function *foo() {
        yield 2;
        return "foo";
    }
    
    function *bar() {
        yield 1;
        var v = yield *foo();
        console.log( "v: " + v );
        yield 3;
    }
    
    var it = bar();
    
    it.next() // {value: 1, done: false}
    it.next() // {value: 2, done: false}
    it.next() // "v: foo"
              // {value: 3, done: false}
    it.next() // {value: undefined, done: true}

    9.作为属性的Generator: let obj = { * foo(){}};

    10.Generator函数返回的遍历器对象是函数的实例,也继承了函数的prototype上的方法;

    // 使用this
    function* F() {
        this.a = 1;
        yield this.b = 2;
    }
    var f = F.call(F.prototype);
    
    f.next();  // Object {value: 2, done: false}
    f.next();  // Object {value: undefined, done: true}
    
    f.a // 1
    f.b // 2

    11.Generator函数的应用:

      - 异步操作可以用同步写法;

      - 控制流管理;

      - 部署Iterator接口;

    12.协程:多个线程互相协作,完成异步任务;Generator函数就是协程在es6的实现,其特点是交出函数的执行权。

    13.Thunk函数其实就是传名调用,将参数放到一个临时函数中,用来替换某个表达式传入函数体。

    function f(m) {
      return m * 2;
    }
    
    f(x + 5);
    
    // 等同于
    
    var thunk = function () {
      return x + 5;
    };
    
    function f(thunk) {
      return thunk() * 2;
    }

    在js中,js是传值调用,Thunk 函数替换的不是表达式,而是多参数函数,将其替换成一个只接受回调函数作为参数的单参数函数。Thunk 函数是自动执行 Generator 函数的一种方法。

    // 正常版本的readFile(多参数版本)
    fs.readFile(file, callback);
    
    // Thunk版本的readFile(单参数版本)
    var Thunk = function (file) {
      return function (callback) {
        return fs.readFile(file, callback);
      };
    };
    
    var readFileThunk = Thunk(file);
    readFileThunk(callback);
  • 相关阅读:
    Winform 打包,卸载程序制作获取ProductCode
    委托/事件的重写
    反序列化无法找到程序集
    Control.Invoke注意事项
    操作config文件
    MemoEdit自动滚动到结尾
    读取局域网内的共享文件
    命令行卸载程序
    获取执行程序的路径
    SCSF 系列:使用 Visualizer 监控 SCSF 运行状态
  • 原文地址:https://www.cnblogs.com/colima/p/6904782.html
Copyright © 2020-2023  润新知