【问题标题】:Consume async iterable without variable declaration使用没有变量声明的异步迭代
【发布时间】:2020-03-22 08:12:22
【问题描述】:

使用同步 JavaScript 生成器,我可以按如下方式对其进行迭代:

(() => {
  function * syncGenerator () {
    yield 1
    yield 2
    yield 3
    console.log('done')
  }

  Array.from(syncGenerator())
})()

这将简单地迭代整个生成器,而无需初始化变量。我想对异步生成器做同样的事情。我能想到的最接近的解决方案如下:

(async () => {
  async function * asyncGenerator () {
    yield Promise.resolve(1)
    yield Promise.resolve(2)
    yield Promise.resolve(3)
    console.log('done')
  }

  for await (const num of asyncGenerator()) {}
})()

不幸的是,我不得不在上面的代码 sn-p 中实例化变量num。这会导致 StandardJS 在该行给出错误,因为未使用该变量。有什么方法可以迭代异步生成器而无需创建变量?

【问题讨论】:

  • 这可能有点 XY-ish;为什么 StandardJS 存在变量存在问题?
  • iterator helpers proposal 将有一个 toArray 方法
  • 如果promise需要按顺序构建和解析,使用.then()。如果顺序无关紧要,请使用Promise.all()
  • @IceMetalPunk StandardJS 抱怨该变量已初始化,但未使用。为了清楚起见,我会更新我的问题。
  • 看起来没有异步生成器理解。或者,StandardJS 确实提供了hide certain warnings 的方法。

标签: javascript ecmascript-6 async-await generator es6-promise


【解决方案1】:

当前解决方案

根据问题的 cmets 和我自己的研究,我在撰写本文时对问题的首选解决方案如下:

(async () => {
  async function * asyncGenerator () {
    yield Promise.resolve(1)
    yield Promise.resolve(2)
    yield Promise.resolve(3)
    console.log('done')
  }

  // eslint-disable-next-line no-unused-vars
  for await (const num of asyncGenerator()) {}
})()

注意// eslint-disable-next-line no-unused-vars 注释,它禁止 StandardJS 为该行生成警告。

未来的解决方案

一旦Iterator Helpers 提案成熟并可用,就可以对同步和异步生成器执行以下操作:

function * syncGenerator () {
  yield 1
  yield 2
  yield 3
  console.log('sync done')
}

syncGenerator().forEach(() => {}) // Logs 'sync done'

async function * asyncGenerator () {
  yield Promise.resolve(1)
  yield Promise.resolve(2)
  yield Promise.resolve(3)
  console.log('async done')
}

asyncGenerator().forEach(() => {}) // Logs 'async done'

【讨论】:

    【解决方案2】:

    这是另一种方法

        async function * asyncGenerator(): AsyncIterableIterator<number> {
            yield Promise.resolve(1)
            yield Promise.resolve(2)
            yield Promise.resolve(3)
            console.log('async done')
        }
        const it: AsyncIterableIterator<number> = asyncGenerator()
        while (true) {
            const result: IteratorResult<number> = await it.next();
            if (result.done) break;
        }
    

    (为文档目的添加的 TypeScript 类型)

    当然,这确实声明了变量it,但它并没有被使用,我相信这是你的实际问题。

    也就是说,我的 ESLint 确实抱怨过使用 while (true)(配置为 eslint:recommended),我个人觉得这有点愚蠢,但对你来说可能是也可能不是问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多