假设我们有以下生成器函数:
var gen1 = function * (){
yield 1;
};
我们还有两个生成器产生以上生成器:
var gen2 = function * () {
yield gen1;
};
var gen3 = function * () {
yield *gen1;
};
有人知道 之间有什么区别吗yield gen1
yield *gen1
?发电机有什么作用*
?
假设我们有以下生成器函数:
var gen1 = function * (){
yield 1;
};
我们还有两个生成器产生以上生成器:
var gen2 = function * () {
yield gen1;
};
var gen3 = function * () {
yield *gen1;
};
有人知道 之间有什么区别吗yield gen1
yield *gen1
?发电机有什么作用*
?
你的代码的效果是这样的:
for (let x of gen1()) console.log(x) // "1"
for (let x of gen2()) console.log(x) // "function* gen1() { yield 1; }"
for (let x of gen3()) console.log(x) // throws TypeError
你的意思可能是:
var gen2 = function* () {
yield gen1();
};
var gen3 = function* () {
yield* gen1();
};
在这种情况下,您会得到:
for (let x of gen2()) console.log(x) // "[object Object]"
for (let x of gen3()) console.log(x) // "1"
也就是说,plainyield
只返回操作数表达式的计算结果(在 的情况下gen2
,未使用的迭代器对象)。yield*
另一方面, A委托给另一个迭代器。它将产生迭代器产生的任何东西,直到它被耗尽。更具体地说:
function* g() { yield 1; yield 2; yield 3 }
function* h() { yield 4; yield* g(); yield 5 }
function* i() { yield 6; yield* h(); yield 7 }
for (let x of i()) console.log(x) // 6, 4, 1, 2, 3, 5, 7
引用:
yield*
操作员委托给另一个生成器。这为组成生成器提供了一种方便的机制。
表达式yield* <<expr>>
等价于:
let (g = <<expr>>) {
let received = void 0, send = true, result = void 0;
try {
while (true) {
let next = send ? g.send(received) : g.throw(received);
try {
received = yield next;
send = true;
} catch (e) {
received = e;
send = false;
}
}
} catch (e) {
if (!isStopIteration(e))
throw e;
result = e.value;
} finally {
try { g.close(); } catch (ignored) { }
}
result
}
这类似于for-in
生成器上的循环,不同之处在于它将通过外部生成器的throw
方法抛出的异常传播到委托的生成器中。
来源: http ://wiki.ecmascript.org/doku.php?id=harmony:generators#delegating_yield
我没有花太多时间来完全理解它,但yield* gen;
似乎类似于yield gen();
如果我错了就纠正我(尽管我完全怀疑会有一些极端情况,例如任何异常的上下文。)