Generator
Generator 对象由生成器函数返回并且它符合可迭代协议和迭代器协议。
Generator 生成器是 ES6 提供的一种异步编程解决方案。拥有在函数块中暂停和恢复代码执行的能力。
执行 Generator 生成器 会返回一个 ( Iterator )迭代器对象,也就是说:Generator 函数除了状态机,还是一个迭代器对象生成函数,返回的迭代器对象,可以依次遍历 Generator 函数内部的每一个状态。
function* foo() {
yield 0;
yield 1;
}
function* bar() {
yield 'x';
// 可以在Generator函数里面再套一个Generator
yield* foo();
yield 'y';
}
for (let v of bar()){
console.log(v);// 输出: x 0 1 y
};
注意:
- function 关键字 和 函数名中间有一个 * 号
- 函数体内部使用
yield表达式,定义不同的内部状态 - 需要注意的是,
yield不能跨函数 - 箭头函数不能用做
generator Generator构造函数并不是全局可用。Generator的实例必须从生成器函数返回
方法使用
Generator.prototype.next(value)
该方法返回一个包含属性 done 和 value 的对象。也可以通过接受一个参数用以向生成器传值。 因为每个 next() 方法传入的值都是上一个 yield 表达式的返回值,所以第一个 next() 传入的值是无效的,只有第二次使用才会生效。
返回的对象包含两个属性:
value为返回的值done布尔值, 如果Interator未遍历完毕, 他会返回false, 否则返回true;
function* fib(max) {
let a = 0,
b = 1,
n = 0;
while (n < max) {
yield a;
[a, b] = [b, a + b];
n ++;
}
}
let f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: false}
f.next(); // {value: undefined, done: true}
Generator.prototype.return(value)
返回给定的值并结束生成器。
function* gen() {
yield 1;
yield 2;
yield 3;
}
let g = gen();
g.next(); // { value: 1, done: false }
g.return("foo"); // { value: "foo", done: true }
g.next(); // { value: undefined, done: true }
- 如果生成器调用
return(value),则生成器将保持在“完成”状态。 - 如果没有提供参数,则返回对象的
value属性值为undefined。 - 如果提供了参数,则参数将被设置为返回对象的
value属性的值。
Generator.prototype.throw(exception)
- 可以在函数体外抛出错误,然后在 Generator 函数体内捕获。
- 如果没有在 Generator 函数体内设置 try... catch 代码块,那么抛出的错误会直接被外部的 catch 代码块捕获,如果 Generator 函数体内部和外部都没有部署 try...catch 代码块,那么程序将报错,直接中断执行。
- throw 抛出的错误如果想被内部捕获,最少需要执行一次 next 方法。如果没有执行就会直接被外部的 catch 代码块捕获。
function* gen() {
try {
yield;
} catch (e) {
console.log('内部捕获', e)
}
}
let i = gen();
i.next();
try {
i.throw('a');
i.throw('b');
} catch (e) {
console.log('外部捕获', e);
}