Search code examples
javascriptecmascript-6generatoryield

JavaScript Generators - How to skip yield when called using .next() ?


JavaScript generators allow you to yield actions in a procedural manner.

Is it possible to skip/invoke specific yields natively?

Given the below example, how could this be achieved?

I would like to yield values 1, 3 & 5.

function *getVal() {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    yield 5;
} 


let x = getVal();

// I want to yield ONLY values 1 , 3 , & 5

// Here val will equal 1
let val = x.next();

// I now want to val to equal 3
val = << skip second yield and hit 3 >>

// Is it possible to skip a yield natively?
// ...


Solution

  • Generators follow the javascript iterator protocol, so there aren't many options to control them beyond calling next().

    But, since you are in control of the logic of the generator, you can define the behavior you want for each of those calls to next(). If you want to skip numbers, just make a way to communicate that to the generator.

    For example, this generator will make consecutive numbers, but skip based on the number passed into next()

    function *getVal() {
        let n = 1;
        let skip = 0
        while (n <= 15){
            skip =  yield n
            n = n+1+ (skip || 0)
        }
    } 
    
    
    let x = getVal();
    
    console.log(x.next().value);  // start with 1
    console.log(x.next(1).value); // skip two
    console.log(x.next().value)
    console.log(x.next(2).value)  // skip 5 and 6
    console.log(x.next(1).value); // skip 8
    //etc.