Javascript 在承诺迭代器上迭代的非递归方法

Javascript 在承诺迭代器上迭代的非递归方法,javascript,promise,Javascript,Promise,我开发了一个客户端库,它公开了一个名为iterator()的方法。此方法返回使用require('Promise')library创建的Promise实例,该实例由迭代器对象完成 此对象包含一个名为next()的方法,该方法返回一个由以下复杂对象完成的承诺:{done:[true | false],key:u,value:} 尽管iterator()可能会预取一些元素,next()需要返回一个承诺,以防它导致远程调用 现在,假设用户希望迭代所有元素,直到next()返回的承诺返回一个包含done

我开发了一个客户端库,它公开了一个名为
iterator()
的方法。此方法返回使用
require('Promise')
library创建的Promise实例,该实例由迭代器对象完成

此对象包含一个名为
next()
的方法,该方法返回一个由以下复杂对象完成的承诺:
{done:[true | false],key:u,value:}

尽管
iterator()
可能会预取一些元素,
next()
需要返回一个承诺,以防它导致远程调用

现在,假设用户希望迭代所有元素,直到
next()
返回的承诺返回一个包含
done:true
的对象

我已经通过以下递归方法实现了这一点(我最初是在这里找到这个解决方案的):

var iterate=client.iterator();
iterateTeams.then(函数(it){
函数循环(promise,fn){
//迭代器的next()调用上的简单递归循环
返回承诺。然后(fn)。然后(函数(条目){
return!entry.done?循环(it.next(),fn):entry;
});
}
返回循环(it.next(),函数(entry){
console.log('条目为:'+条目);
返回条目;
});
});
问题是,是否可以使用
require('promise')
库构建非递归解决方案?我对非递归方法感兴趣的原因是,如果要迭代的条目数太多,就避免爆发

干杯,
Galder

没有新语法或库-通常没有

如果您使用的是babel,那么可以使用ES2018(:p)异步迭代:

for await (const team of iterateTeams) {
   // do something with team
}

否则,您可以使用具有ES2016异步/等待语法的生成器:

for(var it = iterateTeams(); !done; ({done, value}) = await it.next()) {
    // work with value
}     
或使用今天提供的ES2015发电机语法和泵,通过:

我对非递归方法感兴趣的原因是,如果要迭代的条目数太多,就避免爆发

不要害怕。异步“递归”(有时被称为)不会增加调用堆栈,它很像尾部递归。你永远不会得到stackoverflow异常


如果promise库得到合理的实现,这甚至不会增加内存-有关详细信息,请参阅。

听起来您在寻找生成器或可观察的。您可以使用另一种解决方案来隐藏递归,但它仍然是递归解决方案。Galder,您可能想阅读标题为“收集混乱”我们还没到,但已经到了:)请看答案。@Roamer-1888,谢谢你的指针,但该部分假设你有一个数组或知道需要循环多少个元素,因此不适用于这里。非常感谢这些解决方案,但这些都不适用于我。我使用的是ES2015,需要Node.js 0.10(bluebird Promise.coroutine需要Node.js 0.12)@GalderZamarreño如果您使用的是NodeJS 0.10,那么您如何使用ES2015?此外,如果没有递归或一个本身执行递归的帮助器方法,答案仍然有效-在ES2015之前是不可能的抱歉,被搞糊涂了,意思是ES5和Node.js 0.10。然后,不,您必须使用递归或一个将使用递归本身的帮助器函数-有效地将
循环
函数牵引到助手。
// inside a Promise.corutine  
for(var it = iterateTeams(); !done; ({done, value}) = yield it.next()) {
   // work with value
}