Краткое частичное применение асинхронного генератора 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);
}