Generator Yields No Value
ID |
javascript.generator_without_yield_value |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
correctness, generator, reliability |
Description
Reports a yield with no operand written as a statement of its own inside a generator.
yield; is legal and means yield undefined: the consumer’s next() answers { value: undefined, done: false }, which is indistinguishable from a sequence element that genuinely is undefined.
The other use of a bare yield is deliberate and is not reported: a generator driven as a coroutine reads the value its consumer passes to next(value) back out of the yield expression, and writes it const command = yield; or state = yield;. What separates the two is whether the yield’s own value is consumed, so only a bare yield whose result is discarded is a finding.
A cooperative scheduler that uses yield; purely to suspend is the one legitimate case this cannot tell apart, which is why the rule ships at low severity.
Rationale
// Bad
function* rows(table) {
for (const row of table) {
yield; // yields undefined, not the row
}
}
-
It reads as a statement that hands something over and behaves as one, so nothing fails at the generator.
-
A
for…ofover the generator walks anundefinedfor every element, and a spread produces a run of holes. -
Code that keys on the yielded element throws far from the generator, with a message about
undefinedthat names the consumer instead. -
The mistake is a single omitted operand, and no run will ever point at it.
Remediation
Yield the value.
// Good
function* rows(table) {
for (const row of table) {
yield row;
}
}