美文网首页
ES6 - Generator

ES6 - Generator

作者: 明里人 | 来源:发表于2019-08-15 11:36 被阅读0次

    generator(生成器)是ES6标准引入的新的数据类型,与函数类似,但它可以返回多次。
    generator由 function * 定义,并且除了使用return,还可以通过定义 yield 返回多次。
    generator不像普通函数一样,调用就会执行,需要通过next()方法执行:

    function* helloGenerator() {
      console.log('this is generator');
    }
    var h = helloGenerator(); // 这里调用不会执行console
    h.next(); // 执行console
    
    例子:

    要编写一个斐波那契数列的函数:

    function fib(max) {
      var t, a = 0, b = 1, arr = [0, 1];
      while (arr.length < max) {
        [a, b] = [b, a + b];
        arr.push(b);
      }
      return arr;
    }
    console.log(fib(5)); // [0, 1, 1, 2, 3]
    

    函数只能返回一次,使用generator,可以实现返回多次结果。

    function* fib(max) {
      var t, a = 0, b = 1, arr = [0, 1];
      while (arr.length < max) {
        [a, b] = [b, a + b];
        arr.push(b);
        yield arr;
      }
      if (max === 2) {
        return arr
      }
     }
    

    fib() 仅仅创建了一个generator对象,还没有去执行它。
    执行generator有两种方式:
    1、next() 方法:

    var fun = fib(5);
    console.log(fun.next()); // {value: Array(3), done: false}
    console.log(fun.next()); // {value: Array(4), done: false}
    console.log(fun.next()); // {value: Array(5), done: false}
    console.log(fun.next()); // {value: undefined, done: true}
    

    next() 方法会执行generator代码,每次遇到 yield,就会返回一个对象 {value: x, done: true / false}。value 就是 yield 的返回值,done为true时,表示这个generator已经全部执行完毕。
    2、for ... of循环迭代generator对象

    for (var arr of fib(5)) {
        console.log(arr)
    }
    // (3) [0, 1, 1]
    // (4) [0, 1, 1, 2]
    // (5) [0, 1, 1, 2, 3]
    

    这种方式没有返回值done,会自动判断可执行的yield。

    解决回调地狱,异步代码按同步执行:
    function prepare(success) {
        setTimeout(function() {
            console.log('prepare');
            success(); // 执行成功后再执行下一个next()方法
        },500)
    }
    function fired(success) {
        setTimeout(function() {
            console.log('fired');
            success(); // 执行成功后再执行下一个next()方法
        },500)
    }
    function stewed(success) {
        setTimeout(function() {
            console.log('stewed');
            success(); // 执行成功后再执行下一个next()方法
        },500)
    }
    function sdd(success) {
        setTimeout(function() {
            console.log('sdd');
            success(); // 执行成功后再执行下一个next()方法
        },500)
    }
    function serve(success) {
        setTimeout(function() {
            console.log('serve');
            success(); // 执行成功后再执行下一个next()方法,此时返回结果done为true
        },500)
    }
    function* task() {
        yield prepare;
        yield fired;
        yield stewed;
        yield sdd;
        yield serve;
    }
    function run(fn) {
        const gen = fn();
        function next() {
            const result = gen.next();
            if (result.done) return;
            
            result.value(next);
        }
        next();
    }
    run(task);
    // 执行结果:
    // prepare
    // fired
    // stewed
    // sdd
    // serve
    

    相关文章

      网友评论

          本文标题:ES6 - Generator

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