How to conditionally stop a JavaScript generator?

c#, generator, iterator, javascript

Solution

I've decided to verify this experimentally with the following code:

function checker(i) {
  return i !== 2;
}

function* idMakerReturn(){
    let index = 0;
    while(index < 3)
        if (checker(index))
            yield index++;
        else
            return;
}

function* idMakerBreak(){
    let index = 0;
    while(index < 3)
        if (checker(index))
            yield index++;
        else
            break;
}

const a = idMakerReturn();
console.log('1', a.next());
console.log('2', a.next());
console.log('3', a.next());

const b = idMakerBreak();
console.log('1', b.next());
console.log('2', b.next());
console.log('3', b.next());

Both variants correctly return `{ "done": true, "value": undefined }` when broken out from. I did also check this with TypeScript by observing the inferred function type.

function* idGen(seed: string | undefined) {
  if (!seed) {
    return; // Or `break`
  }

  const something = seed.trim();
}

With `return` everything works correctly and the function return type is `IterableIterator<T>`.

With `break` I am asked to provide a label to jump to and also `something` is no longer inferred to be safe to access (just `string` because the `undefined` is handled by the `if`), but remains a `string | undefined`.

This leads me to conclude that as Felix says, anything that terminates the generator function will correctly yield the `done: true` item, but it seems that `return` is preferable because escape analysis works with it whereas it doesn't with `break`.

Still have not been able to find official word on this, but it's good enough for me.

Problem

With an iterator like the following one: ``` function* idMaker(){ let index = 0; while(index < 3) yield index++; } ``` How can I make sure to stop the generator prematurely based on a condition? ``` function* idMaker(){ let index = 0; while(index < 3) if (checker(index)) yield index++; else return; } ``` Is it okay appropriate to use in a generator? Should I use `break` instead of `yield break` perhaps like in C#? Can you include a link to MDN or spec where this is discussed?

Original source