前端开发知识

function* 生成器函数

2019-03-18  本文已影响0人  CRJ997

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

定义方式

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

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

2.通过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"之后就直接没了。
上一篇下一篇

猜你喜欢

热点阅读