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
- 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"之后就直接没了。
网友评论