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
}