Краткое частичное применение асинхронного генератора ES2018?

У меня определена функция асинхронного генератора, и я хочу создать вторую функцию асинхронного генератора, которая является частичным применением первой функции. Например, это работает:

async function* fn1(a, b) {/* do something */}

async function* fn2() {
  const a1 = fn1(0, 0);
  for await (const value of a1) {
    yield value;
  }
}

Мой вопрос: есть ли более лаконичный способ определить fn2?

2 ответа

Решение

fn1 возвращает асинхронную итерацию, которая fn2 повторяется, поэтому вместо повторения вручную в fn2, вы можете просто создать итерацию, созданную из fn1 и разреши fn2Потребитель обрабатывает это:

async function* fn2() {
  yield* fn1(0, 0);
}

const delay = ms => new Promise(res => setTimeout(res, ms));
async function* fn1(a, b) {
  for (let i = 0; i < 3; i++) {
    await delay(1000);
    yield i;
  }
}

async function* fn2() {
  yield* fn1(0, 0);
}

(async () => {
  for await (const val of fn2()) {
    console.log('Consumer got', val);
  }
  console.log('Done');
})();

// Original version, without yield* (just to illustrate equivalence):

const delay = ms => new Promise(res => setTimeout(res, ms));
async function* fn1(a, b) {
  for (let i = 0; i < 3; i++) {
    await delay(1000);
    yield i;
  }
}

async function* fn2() {
  const a1 = fn1(0, 0);
  for await (const value of a1) {
    yield value;
  }
}

(async () => {
  for await (const val of fn2()) {
    console.log('Consumer got', val);
  }
  console.log('Done');
})();

Наиболее краткого определения можно добиться, просто не делая fn2функция генератора. Используйте обычную функцию, которая возвращает генератор - генератор, созданный вызовомfn1:

function fn2() {
  return fn1(0, 0);
}
Другие вопросы по тегам