【问题标题】:Concise partial application of ES2018 Async Generator?ES2018 Async Generator 的简明部分应用?
【发布时间】:2020-03-30 23:59:19
【问题描述】:

我定义了一个异步生成器函数,并想创建第二个异步生成器函数,它是第一个函数的部分应用。例如,这有效:

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

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

我的问题是:有没有更简洁的方式来定义fn2

【问题讨论】:

  • 我在这里没有看到任何“部分”?

标签: javascript async-await ecmascript-2018


【解决方案1】:

最简洁的定义可以通过简单地不使fn2 成为生成器函数来实现。使用返回生成器的普通函数——调用fn1创建的生成器:

function fn2() {
  return fn1(0, 0);
}

【讨论】:

    【解决方案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');
    })();

    【讨论】:

    • 啊! yield* 是我正在寻找的语法。谢谢!
    • 您可能需要添加 return 关键字,以便生成器的最终结果也能传播
    猜你喜欢
    • 2018-11-01
    • 2018-09-11
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 2018-04-28
    • 2018-11-27
    相关资源
    最近更新 更多