37

ECMAScript 6 は、ジェネレーター関数とイテレーターをもたらすはずです。ジェネレーター関数 (function*構文を持つ) は反復子を返します。イテレーターには、next繰り返し呼び出されるとジェネレーター関数の本体を実行し、すべてのyieldオペレーターで実行の一時停止と再開を繰り返すメソッドがあります。

ジェネレーターに関するECMAScript 6 wiki では、次のように「委譲された yield」yield*演算子も紹介されています。

オペレーターはyield*別のジェネレーターに委任します。これは、ジェネレーターを構成するための便利なメカニズムを提供します。

「別のジェネレーターに委任する」とはどういう意味ですか? yield*「ジェネレーターを便利に構成する」にはどうすればよいですか?

[ノード v0.11.3 のジェネレーターで--harmony-generatorsフラグを使用して遊ぶことができます。]

4

3 に答える 3

50

別のジェネレーターに委譲するということは、現在のジェネレーターがそれ自体で値を生成するのを停止し、代わりに別のジェネレーターによって生成された値を使い果たすまで生成することを意味します。その後、独自の値があれば生成を再開します。

たとえば、secondGenerator()が から10までの数値を生成し15、から までの数値を生成するが、 が を生成した後に に委譲する場合、 によって生成される値は次のようになります。firstGenerator()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 に答える
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 しか受け取りません。超過利回り *コールは効果がありません。

  2. 内部ジェネレーターのdone値は、その呼び出し元が返すdoneには影響しません。

  3. 出力は未定義を示しています! ジェネレーターのdone = trueを示すために、必要な値の数を 1 つ超えるようにテスト ループが記述されているため、最後に

  4. この出力は ES6 のテスト グラウンドであるBabelからのものであり、上記のセマンティクスは 2016 年 2 月 5 日時点で暫定的なものと見なされます。

于 2016-02-05T16:22:00.350 に答える