📦yield
JS ⟩ objects ⟩ built-in ⟩ Generator ⟩ generator function ⟩ yield
JS ⟩ statement ⟩ control flow ⟩ jump ⟩ yield
(used only in generator functions) to produce the next value without returning.
yield and yield* operator can only be used within generator functions❗️
// this seems like a generator function, but there's a catch ...
function* sequence(...iterables) {
// --------------------------------------------------------------
// ⭐ `yield/yield*` only available within generator functions❗
// --------------------------------------------------------------
// ❌ but this `yield*` is within an "arrow function"❗
//
// ╭─── 🔸 arrow function ───╮
iterables.forEach( iterable => yield* iterable );
// ^^^^^^
// ⛔ ReferenceError: yield is not defined
}
the value of the current yield
when the "expression after yield" is evaluated and yielded, the execution of the generator code stops right there, and the value of the "yield expression" itself is still undefined and waiting for the next call of next() to send it in. (will remain undefined if there's no further next() call any more)
can be considered as a new starting point for the next call of next().
const { log } = console;
// generator code
function* ints() {
// argument to the `next(arg)` method
// ---------------------------------------------
// `arg`:
// • is the "value" of PREVIOUS "yield expression".
// • is ignored in the first call of next().
// (since there's NO previous yield expression)
// • can be considered a "new starting point" for
// the "current" call of next() method.
// (except for the first call, in which `arg` is ignored)
// #1 next() call
// ---------------
// ╭─1─╮ // 1. value for #1 call
const arg2 = yield 1 ; // (execution stops at Y.E.)
// ╰─ 2 ─╯ ╰── Y.E. ──╯ // Y.E. : yield expression
// #2 next() call
// --------------
// 2. argument sent in by #2 call
// ╭── 3 ──╮ // 3. value for #2 call
const arg3 = yield [2, arg2]; // (execution stops at Y.E.)
// ╰─ 4 ─╯ ╰──── Y.E. ───╯ //
// #3 next() call
// --------------
// ╭── 5 ──╮ // 4. argument sent in by #3 call
return [3, arg3]; // 5. "done" value for #3 call
// (the iteration is finished)
}
// table settings
const headers = [' ', 'value', 'done'];
const n = headers.length; // number of columns
const [colWidth, pad, ext] = [5, 1, 0];
const line = '-'.repeat(colWidth*n + pad*(n-1) + ext);
log(` value done`);
log(line);
// log iteration result
function logResult(r, i) {
let value = r.value === undefined ? 'x' : String(r.value);
value = value.padEnd(5, ' ');
const done = (r.done ? '✅' : '❌').padEnd(4, ' ');
log(`#${i}: ${value} ${done}`);
}
// main
let it = ints();
const r1 = it.next('a'); // #1 next() call
logResult(r1, 1);
const r2 = it.next('b'); // #2 next() call
logResult(r2, 2);
const r3 = it.next('c'); // #3 next() call
logResult(r3, 3);
// output:
//
// value done
// -----------------
// #1: 1 ❌
// #2: 2,b ❌
// #3: 3,c ✅
Last updated