给迭代器传递参数
迭代器向外传值:
- 在生成器内部使用
yield语句返回值。 - 给迭代器的
next()传递参数,则这个参数会替代生成器中一条yield语句的返回值
function *createIterator() {
let first = yield 1;
let second = yield first + 2;
yield second + 3;
}
let iterator = createIterator();
iterator.next(); //"{ value: 1, done: false}"
iterator.next(4); //"{ value: 6, done: false }"
iterator.next(5); //"{ value: 8, done: false}"
iterator.next(); //"{ value: undefined, done: true}"
注意点
- 第一次调用
next()方法时传参是无效的,因为next()方法的参数是替代上一次yield语句的返回值。 - 每次执行
next()方法时,执行完赋值右边的yield之后就会暂停,直到下一次next()才会执行前一个yield语句的赋值。
在迭代器中抛出错误
迭代器不仅提供了 next() 方法传参,还提供了 throw() 方法抛出错误。通过 throw() 方法,当迭代器恢复执行时可令其抛出一个错误,然后中断后续代码的执行。
iterator.throw(new Error('Boom'))
可以在代码块内部使用 try-catch 捕获这些错误,使得就算出现错误,也可以继续向下执行。
在迭代器内,如果使用了 yield 语句,可以通过 next() 和 throw() 控制执行过程,也可以使用 return 语句返回一些不一样的内容。
生成器返回语句
在生成器中,return 表示操作完成,其后的语句都不会执行,所以会将 done 属性置为 true,将 value 属性置为 return 的返回值,没有返回值为 undefined。
function *createIterator() {
yield 1;
return 42;
yield 2;
}
let iterator = createIterator();
iterator.next(); //"{ value: 1, done: false}"
iterator.next(); //"{ value: 42, done: true}"
iterator.next(); //"{ value: undefined, done: true}"
通过 return 指定的返回值,只会在返回对象中出现一次,在后续调用中,value 会被重置为 undefined。
委托生成器
合并两个生成器
合并两个生成器,只需要新建一个生成器,然后将这两个生成器的 name 放在其中的 yield 后面即可,中间需要加上星号。
function *createCombinediterator() {
yield *createiterator1();
yield *createiterator2();
yield 'hello';
yield *'hello';
}
这里的 createCombinediterator 生成器先后委托了 createiterator1 和 createiterator2 两个生成器。
这里值得注意的是,
yield 'hello'在调用 next() 时会返回 hello 这个字符串。而yield *'hello'会调用 hello 这个字符串的默认迭代器,也就是一个字符一个字符的返回。
异步任务执行
我们希望每隔 1000ms 输出1、2、3,但又不想多层回调函数嵌套使用,就可以使用生成器来简化。
function task(gen){
let iterator = gen();
result = iterator.next();
function step(){
setTimeout(() => {
if(!result.done){
result = iterator.next();
step();
}
}, 1000);
}
step();
}
function* gen(){
console.log(1);
yield;
console.log(2);
yield;
console.log(3);
}
function task3() {
console.log(6);
}
task(gen);