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