生成器函数可以带有参数,并且会在第一次调用函数时使用这些参数。生成器可以被终止(引起它抛出 StopIteration 异常)通过使用 return 语句。下面的 fibonacci() 变体带有一个可选的 limit 参数,当条件被触发时终止函数。
复制代码 代码如下:
function fibonacci(limit){
var fn1 = 1;
var fn2 = 1;
while(1){
var current = fn2;
fn2 = fn1;
fn1 = fn1 + current;
if (limit && current > limit)
return;
yield current;
}
}
生成器高级特性
生成器可以根据需求计算yield返回值,这使得它可以表示以前昂贵的序列计算需求,甚至是上面所示的无限序列。
除了 next() 方法,generator-iterator 对象还有一个 send() 方法,该方法可以修改生成器的内部状态。传给 send() 的值将会被当做最后一个 yield 表达式的结果,并且会暂停生成器。在你使用 send() 方法传一个指定值前,你必须至少调用一次 next() 来启动生成器。
下面的斐波那契生成器使用 send() 方法来重启序列:
复制代码 代码如下:
function fibonacci(){
var fn1 = 1;
var fn2 = 1;
while (1) {
var current = fn2;
fn2 = fn1;
fn1 = fn1 + current;
var reset = yield current;
if (reset) {
fn1 = 1;
fn2 = 1;
}
}
}
var sequence = fibonacci();
print(sequence.next()); //1
print(sequence.next()); //1
print(sequence.next()); //2
print(sequence.next()); //3
print(sequence.next()); //5
print(sequence.next()); //8
print(sequence.next()); //13
print(sequence.send(true)); //1
print(sequence.next()); //1
print(sequence.next()); //2
print(sequence.next()); //3
注意:有意思的一点是,调用 send(undefined) 和调用 next() 是完全同等的。不过,当调用 send() 方法启动一个新的生成器时,除了 undefined 其它的值都会抛出一个 TypeError 异常。
你可以调用 throw 方法并且传递一个它应该抛出的异常值来强制生成器抛出一个异常。此异常将从当前上下文抛出并暂停生成器,类似当前的 yield 执行,只不过换成了 throw value 语句。
如果在抛出异常的处理过程中没有遇到 yield ,该异常将会被传递直到调用 throw() 方法,并且随后调用 next() 将会导致 StopIteration 异常被抛出。
生成器拥有一个 close() 方法来强制生成器结束。结束一个生成器会产生如下影响:
1.所有生成器中有效的 finally 字句将会执行
2.如果 finally 字句抛出了除 StopIteration 以外的任何异常,该异常将会被传递到 close() 方法的调用者
3.生成器会终止
生成器表达式