美文网首页前端开发知识
function* 生成器函数

function* 生成器函数

作者: CRJ997 | 来源:发表于2019-03-18 15:01 被阅读0次

    ES6中定义了一种新的函数.用function*定义生成器函数,这种函数会返回一个generator对象.生成器函数在执行时可以暂停,然后又可以在暂停处接着执行。

    定义方式

    1.直接按照function*像一般的函数那样子声明.可以带参.

    function* gen(i){
      yield 10;
      yield i+10;
    }
    

    2.通过GeneratorFunction进行生成,步骤比较麻烦.

    • 这边注意一个点就是GeneratorFunction对象并不是一个全局对象.它可以使用如下的方式进行获得.
    Object.getPrototypeOf(function*(){}).constructor
    
    • 使用示例:
    new GeneratorFunction ([arg1[, arg2[, ...argN]],] functionBody)
    //其中的arg1等为字符串类型的写法.
    //functionBody为包含多条js语句的字符串
    //使用示例:
    let GeneratorFunction = Object.getPrototypeOf(function*(){}).constructor;
    let a = new GeneratorFunction("i","yield 20;yield 20+i;");
    let genO = a(12);   //注意这边不能使用构造器语法,也就是不能用new
    console.log(genO.next());// {value:20 , done: false}
    console.log(genO.next());// {value:32,done:true} 
    

    yield的使用

    yield用来在生成器函数中定义暂停位置和进行数值的返回,还有进行执行权的移交(yield *);

    1.简单的示例:

    function* idMaker(){
      var index = 0;
      while(index<3)
        yield index++;
    }
    
    var gen = idMaker();
    console.log(gen.next().value); // 0
    console.log(gen.next().value); // 1
    console.log(gen.next().value); // 2
    console.log(gen.next().value); // undefined
    
    1. Generator.next()函数
      这个函数用来进行语句的执行。在使用生成器函数生成一个generator对象的时候,函数内部的语句并不会马上执行,而是在调用next函数的时候执行到第一个yield语句中,并通过yield来进行值的返回。然后接着调用next()函数,则会执行到后续的yield语句的位置。

    2.1 next函数的返回值。
    next函数返回一个对象,当生成器函数迭代完成并且函数中没有return语句的时候,对象中的value值变成undefined,done变成true。如果有return语句,迭代完成的时候value值为return返回的数值,done的值为true。例如:

    {
     value: 12, // yield后面跟着的字面量值,变量值或者表达式的计算值。或者是最终return语句返回的值,没有return则为undefined
     done: false // 表示生成器函数中是否还有yield语句。false表示还有,true表示已经迭代完成。
    }
    

    2.2 next函数进行传参操作:

    function *createIterator() {
        let first = yield 1;
        let second = yield first + 2; // 4 + 2 
                                      // first =4 是next(4)将参数赋给上一条的
        yield second + 3;             // 5 + 3
    }
    
    let iterator = createIterator();
    
    console.log(iterator.next());    //  "{ value: 1, done: false }"
    console.log(iterator.next(4));   // "{ value: 6, done: false }"  传入的参数4会作为yield的返回值放到上次的暂停处。
    console.log(iterator.next(5));   // "{ value: 8, done: false }"
    console.log(iterator.next());    // "{ value: undefined, done: true }"
    

    3.yield*进行执行权的移交。

    function* anotherGenerator(i) {
      yield i + 1;
      yield i + 2;
      yield i + 3;
    }
    
    function* generator(i){
      yield i;
      yield* anotherGenerator(i);// 移交执行权
      yield i + 10;
    }
    
    var gen = generator(10);
    
    console.log(gen.next().value); // 10
    console.log(gen.next().value); // 11
    console.log(gen.next().value); // 12
    console.log(gen.next().value); // 13
    console.log(gen.next().value); // 20
    

    显式返回

    当在生成器函数中直接用return返回数值的时候,之后的语句(包括yield语句)将不再执行。

    function* yieldAndReturn() {
      yield "Y";
      return "R";//显式返回处,可以观察到 done 也立即变为了 true
      yield "unreachable";// 不会被执行了
    }
    
    var gen = yieldAndReturn()
    console.log(gen.next()); // { value: "Y", done: false }
    console.log(gen.next()); // { value: "R", done: true }
    console.log(gen.next()); // { value: undefined, done: true }  返回"R"之后就直接没了。
    

    相关文章

      网友评论

        本文标题:function* 生成器函数

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