generator(生成器)是 ES6 标准引入的新的数据类型。一个 generator 看上去像一个函数,但可以返回多次。
generator 函数和普通的函数区别有两个, 1:function 和函数名之间有一个*号, 2:函数体内部使用了 yield 表达式
调用 生成器函数 和调用 普通函数不同,调用生成器函数是返回一个 生成器对象(可迭代的对象)
// * 和 yield
function* gen() {
yield "1";
yield 2;
}
let iter = gen(); // 创建生成器对象 iter(可迭代)
next()
调用 生成器对象的 next() 方法,才是真正开始执行生成器函数,每次遇到 yield 或者 return 就会返回一个对象{value: "1", done: false}
value 表示 yield 或 return 后面的值。
done 表示这个 对象是否已经结束(迭代到末尾了)
forof 循环
调用迭代器循环 生成器对象。可以直接获取到 yield 后面的值。
扩展运算符
...生成器对象 也可以获取 yield 后面的值。
【注 1】next()到 return 表示结束(没有 return,其实是隐含了 return undefined),且 return 之后的 yield 不会被执行到
【注 2】done 到最后返回 true,表示结束
【注 3】return 不会被 forof 和扩展运算符遍历到。所以只能用 next()获取到 return 的值
function* gen() {
yield "1";
yield 2;
yield 3;
yield 4;
return 5;
}
let iter = gen();
console.log(iter.next()); // {value: "1", done: false}
for (const i of iter) {
console.log(i); // 从 2 开始,到 4 结束。不会获得return的值
}
console.log(...iter); //不用上面的forof,用扩展运算符得出的结果 和上面是一样的
委托,可以委托给其他生成器或者可迭代对象。
//其他生成器
function* g1() {
yield 2;
yield 3;
yield 4;
}
function* g2() {
yield 1;
yield* g1();
yield 5;
}
var iterator = g2();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: 4, done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
// 可迭代对象
function* g3() {
yield* [1, 2];
yield* "34";
yield* arguments;
}
var iterator = g3(5, 6);
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: "3", done: false }
console.log(iterator.next()); // { value: "4", done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: 6, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
如果给 next 方法传参数, 那么这个参数将会作为上一次 yield 语句的返回值 ,这个特性在异步处理中是非常重要的, 因为在执行异步代码以后, 有时候需要上一个异步的结果, 作为下次异步的参数
function* foo(x) {
var y = 2 * (yield x + 1);
var z = yield y / 3;
return x + y + z;
}
var a = foo(5);
console.log(a.next()); // 6
console.log(a.next()); // NaN,由于这次next没带参数,相当于上一个x+1为undefined,所以 y == 2 * undefined == NaN
console.log(a.next()); // NaN
var b = foo(5);
console.log(b.next()); // 6
console.log(b.next(12)); // 8
console.log(b.next(13)); // 42
原文:https://www.cnblogs.com/pengnima/p/13051324.html