我如何在JavaScript中使用asynchronous生成器?

我有一个API将返回一个游标获取更多的数据。 我嘲笑了这样的:

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

我想要做的是弄清楚我可以如何使用async / await与发生器一起进行交互。

这基本上是我原型的东西:

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

这个想法是我应该能够创build一个asynchronous生成器,并从该生成器产生,以遍历游标:

 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]取出所有的数据是非常酷的。

唯一的问题是,这是行不通的! Apprently你不能使用function* async function*

 ❯❯❯ 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的stream行图书馆,我一直在探索,但我不认为这是我想要的。

任何想法如何让这个“asynchronous发电机”的概念工作?

你可以通过调用generator函数作为参数,而不使用spread元素, Promise.all()接受一个迭代器作为返回的参数。 请注意, Promise.all()不会按顺序parsing或拒绝传递的Promise对象,尽pipe返回的结果数组与传递的迭代中的元素的顺序相同。

 let api = (value) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(value) }, Math.floor(Math.random() * 3500)) }) }; let values = [1, 2, 3]; let results = []; let gen = function* gen(fn, props) { let i = 0; do { yield fn(props[i]).then(res => {console.log(res); return res}); ++i; } while (i < props.length); } Promise.all(gen(api, values)) .then(data => console.log("complete:", data)) .catch(err => console.log(err));