5

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?
// ...

6
  • 2
    If you want to skip one yield, why not just call x.next() before assigning x.next() to val? Commented Jul 12, 2018 at 21:29
  • 1
    You can't skip a yield, but you can call it and ignore the result. Commented Jul 12, 2018 at 21:32
  • @Ivan Thank you, I'm aware you can just call without assigning, but how about skipping without having to invoke the one that is going to be skipped. Commented Jul 12, 2018 at 21:48
  • @Nicholas, this assumes you know the value that will be yielded by the generator, right? Commented Jul 12, 2018 at 21:51
  • 2
    I think the thing to keep in mind is that a generator still behaves like a function. A yield pauses the function until it starts again, but you can't skip part of a generator from outside any more than you can reach in and skip part of any other function. Commented Jul 13, 2018 at 1:45

2 Answers 2

8

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.

Sign up to request clarification or add additional context in comments.

4 Comments

So you're saying there are no native JavaScript hooks to skip yields? This is a cool approach.
@Nicholas not that I know of — the iterator protocol is pretty simple, you basically have next() at your disposal.
Thank you Mark, if you could include in your answer that there is no native way to skip yields I'll be inclined to accept this answer as a workaround.
Caveat with this being that the first call to next can't skip anything.
1

You can always call the next value without assigning it, then call .next again and assign it:

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


let x = getVal();

let val = x.next().value;   // 1
console.log(val);           

x.next();
val = x.next().value;       // 3
console.log(val);

x.next();
val = x.next().value;       // 5
console.log(val);

This way you are ignoring some of the yielded values.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.