37

ECMAScript 6 应该带来生成器函数和迭代器。生成器函数(具有function*语法)返回一个迭代器。迭代器有一个next方法,当被重复调用时,它会执行生成器函数的主体,在每个yield操作符处重复暂停和恢复执行。

生成器上的ECMAScript 6 wiki还引入了“委托收益”yield*运算符,如下所示:

yield*操作员委托给另一个生成器。这为组成生成器提供了一种方便的机制。

“委托给另一个生成器”是什么意思?我该如何使用yield*“方便地编写生成器”?

[您可以使用标志在 Node v0.11.3 中使用生成器--harmony-generators。]

4

3 回答 3

50

委托给另一个生成器意味着当前生成器停止自行生成值,而是生成另一个生成器生成的值,直到它耗尽它。然后它继续产生自己的值,如果有的话。

例如,如果secondGenerator()从 to 产生数字,并从10to15产生数字,firstGenerator()但在 producer之后委托给,则由 产生的值将是:15secondGenerator()2firstGenerator()

1, 2, 10, 11, 12, 13, 14, 15, 3, 4, 5

function* firstGenerator() {
    yield 1;
    yield 2;
    // Delegate to second generator
    yield* secondGenerator();
    yield 3;
    yield 4;
    yield 5;
}

function* secondGenerator() {
    yield 10;
    yield 11;
    yield 12;
    yield 13;
    yield 14;
    yield 15;
}

console.log(Array.from(firstGenerator()));

于 2013-07-05T15:07:58.227 回答
4

委托 yield 不必只委托给另一个生成器而是委托给任何迭代器,所以第一个答案有点不确定。考虑这个简单的例子:

function* someGenerator() {
    yield 0;
    yield [1,2,3];
    yield* [1,2,3];
}

for (v of someGenerator()) {
    console.log(v);
}

生成器本身内部没有其他函数 - 但yield* [1, 2, 3]委托给该Array.prototype[@@iterator]方法。

于 2017-05-24T01:16:41.207 回答
3
function *gimme1to2_10to15_3to5() {
    var ten = gimme10to15();
    yield 1; yield 2;
    for (var i = 10; i <= 20; i++)
        yield *ten;
    yield 3; yield 4; yield 5;
    }

function *gimme10to15() {
    for (var i = 10; i <= 15; i++)
        var x = yield i;
    }

let gen = gimme1to2_10to15_3to5();

var ar = [];
for (var i = 0; i < 12; i++)
    {
    var r = gen.next();
    ar [i] = r.value + (r.done ? "!" : "..");
    }
console.log (ar.join (", "));

结果是

1.., 2.., 10.., 11.., 12.., 13.., 14.., 15.., 3.., 4.., 5.., undefined!

笔记

  1. 带有yield *的函数从内部生成器请求 11 个值,但只接收它应该收到的 10..15。多余的yield *调用无效。

  2. 内部生成器的done值对其调用者返回的done没有影响。

  3. 输出显示未定义!最后,因为测试循环被编写为超出所需数量的值,以显示生成器的done = true

  4. 此输出来自 ES6 测试场Babel,上面展示的语义应被视为截至 2016 年 2 月 5 日的临时性。

于 2016-02-05T16:22:00.350 回答