07. Generators Composition

Композиция — это естественное встраивание одного генератора в поток другого. При композиции значения из вложенного генератора выдаются «по мере готовности». Поэтому она будет работать даже если поток данных из вложенного генератора оказался бесконечным или ожидает какого-либо условия для завершения.

Для комбинирования используется специальная форма yield*. Она применима только к другому генератору и делегирует ему выполнение. То есть, при yield* интерпретатор переходит внутрь генератора-аргумента выполняет его, и все yield, которые он делает, выходят из внешнего генератора. Получается — как будто мы вставили код внутреннего генератора во внешний напрямую:

function* foo() {
  yield "a";
  yield "b";
}

function* bar() {
  yield "x";
  yield* foo();
  yield "y";
}

const arr = [...bar()];
// ['x', 'a', 'b', 'y']

Внутри себя, yield* работает следующим образом:

function* bar() {
  yield "x";
  for (const value of foo()) {
    yield value;
  }
  yield "y";
}

Значением yield* не обязательно должен быть генератор; это может быть любой итерируемый объект. Одно отличие в yield* от обычного в том, что этот операторы учитывает return-значение.

function* generateSequence(start, end) {
  for (let i = start; i <= end; i++) yield i;
}

function* generateAlphaNum() {
  // 0..9
  yield* generateSequence(48, 57);
  // A..Z
  yield* generateSequence(65, 90);
  // a..z
  yield* generateSequence(97, 122);
}

let str = "";
for (let code of generateAlphaNum()) {
  str += String.fromCharCode(code);
}
console.log(str); // 0..9A..Za..z

Last updated