如何在JavaScript中使用异步生成器?

问题描述 投票:3回答:2

我有一个api,它将返回一个光标以获取更多数据。我像这样嘲笑它:

function fetch(n) {
  return Promise.resolve({
    results: [n],
    next: next < 10 && n + 1,
  })
}

我想要做的是弄清楚我如何使用async / await和生成器来与这个api进行交互。

这基本上是我的原型:

async function* api(url) {
  let result = await fetch(url)
  yield result
  while (result.next) {
    result = await fetch(result.next)
    yield result
  }
}

我的想法是,我应该能够创建一个异步生成器并从该生成器中生成以便遍历游标:

async function main() {
  const gen = api(0)
  const zero = await gen.next()
  console.log(zero.result)
  const one = await gen.next()
  console.log(one.result)
  const rest = await Promise.all([...gen])
  console.log(rest.map(r => r.result))
}

考虑到所有事情,我认为这是处理分页数据的一种非常好的方式,并且能够用[...gen]提取所有数据非常酷。

唯一的问题是,它不起作用!显然你不能使用qazxsw poi和qazxsw poi:

async

但我真的觉得这应该是可能的。有一个名为function*的流行图书馆,我一直在寻找,但我不认为这就是我想要的。

任何想法如何让“异步生成器”的概念起作用?

javascript node.js async-await generator
2个回答
1
投票

你可以使用Babel插件❯❯❯ node --version v7.0.0 ❯❯❯ node --harmony --harmony-async-await async-generator.js /Users/chetcorcos/code/async-generator.js:11 async function* api(url) { ^ SyntaxError: Unexpected token * at Object.exports.runInThisContext (vm.js:76:16) at Module._compile (module.js:545:28) at Object.Module._extensions..js (module.js:582:10) at Module.load (module.js:490:32) at tryModuleLoad (module.js:449:12) at Function.Module._load (module.js:441:3) at Module.runMain (module.js:607:10) at run (bootstrap_node.js:382:7) at startup (bootstrap_node.js:137:9) at bootstrap_node.js:497:3 来做到这一点。

用法是这样的:

co

这是transform-async-generator-functions展示如何设置您的项目。

重要的部分是const g = async i => [ 1, 2, 3 ] .map(x => x * 10 ** i); const f = async function * () { for (let i = 0; i < 10; i++) { const xs = await g(i); for (const x of xs) { yield x; } } }; const main = async () => { for await (const x of f()) { console.log(x); } }; main().catch(e => console.error(e)); 文件:

an example repo

0
投票

您可以将生成器函数作为参数调用而不使用spread元素,.babelrc接受一个iterable作为{ "presets": [ "env" ], "plugins": [ "transform-async-generator-functions" ] } 返回的参数。注意,Promise.all()不按顺序解析或拒绝传递的yield对象,但是返回结果数组的顺序与传递的iterable中的元素的顺序相同。

Promise.all()
© www.soinside.com 2019 - 2024. All rights reserved.