Generators: Anidación de Generators

Generators: Anidación de Generators

¿Cómo utilizar generadores dentro de otros?

La sentencia yield* es utilizada para llamar a un generador dentro de otro.

function* funGeneratorA(){
    yield 'a';
    yield 'b';
    yield 'c';
    return 'completada funcGeneratorA()';
}

function funGeneratorB(){
    yield 1;
    yield* funGeneratorA();
    yield 2;
    yield 3;
    return 'completada funcGeneratorB()';
}

var objGenerator = funGeneratorB();

console.log(objGenerator.next()); // { value: 1, done: false }
console.log(objGenerator.next()); // { value: 'a', done: false }
console.log(objGenerator.next()); // { value: 'b', done: false }
console.log(objGenerator.next()); // { value: 'c', done: false }
console.log(objGenerator.next()); // { value: 2, done: false }
console.log(objGenerator.next()); // { value: 3, done: false }
console.log(objGenerator.next()); // { value: 'completada funcGeneratorB()', done: true }

La sentencia yield* no agrega el valor del return de la función generator que es invocada a su lista de iterables, el valor de return puede ser accedido por el valor de retorno de la sentencia yield*.

Vea como la sentencia yield* funcGeneratorA() retorna el valor de retorno de la función funGeneratorA().

function* funGeneratorA() {
    yield "a";
    yield "b";
    return "completada funGeneratorA()";
}

function* funGeneratorB() {
    yield 1;
    var valA = yield* funGeneratorA();
    yield valA;
    yield 2;
    yield 3;
    return "completada funGeneratorB()";
}

var oG = funGeneratorB();

console.log(oG.next()); // { value: 1, done: false }
console.log(oG.next()); // { value: 'a', done: false }
console.log(oG.next()); // { value: 'b', done: false }
console.log(oG.next()); // { value: 'completada funGeneratorA()', done: false }
console.log(oG.next()); // { value: 2, done: false }
console.log(oG.next()); // { value: 3, done: false }
console.log(oG.next()); // { value: 'completada funGeneratorB', done: true }
console.log(oG.next()); // { value: undefined, done: true }

La sentencia yield* puede ser utilizada para iterar cualquier valor iterable ademas de funciones generator.

Ejemplo de yield* utilizando los valores dentro de un arreglo.

function* funGenerator() {
    yield 1;
    yield* [2, 3, 4]; // arreglo iterable
    yield 5;
}

var oG = funGenerator();

console.log(oG.next()); // { value: 1, done: false }
console.log(oG.next()); // { value: 2, done: false }
console.log(oG.next()); // { value: 3, done: false }
console.log(oG.next()); // { value: 4, done: false }
console.log(oG.next()); // { value: 5, done: false }
console.log(oG.next()); // { value: undefined, done: true }