2015-06-16 22 views
3

根据这个link(新手错误#2),我不应该在Promises中使用循环,而应该使用Promise.all(iterable)在Promises中使用循环的正确方法

这是否真的适用于所有循环? Promise.all(iterable)需要大小为n的数组。如果我使用Promise.all(iterable),那么我会得到一个大小为n的数组(即iterable_A)。

如果我想迭代iterable并只想将某些满足我的条件的元素放到另一个迭代器(例如iterable_B)并想要返回iterable_B而不是iterable_A,该怎么办?我是否也应该使用Promise.all()

+2

您可以在promise中使用循环,只要它们不需要太多时间来执行,并且您不会在循环中执行任何异步任务。 – SpiderPig

+0

啊,是的。这就说得通了。上面链接中的文章对此并不清楚。它给人的印象是所有的循环都被禁止承诺。 – thadeuszlay

+0

[正确的方式来编写承诺的循环]的可能的重复。(http://stackoverflow.com/questions/24660096/correct-way-to-write-loops-for-promise) – djechlin

回答

4

我不应该使用的承诺内环路

没有,而是倒过来:你不应该在循环中使用的承诺。

当然这也太泛化了。有时你只需要一个循环结构。你不能做的是忘记收集在循环主体中创建的承诺,在某些迭代中你可以传递给Promise.all,以等待在该循环中启动的所有异步事件。

如文章中建议的map method很自然地这样做,您只需要return承诺从回调(一如既往)。使用for/while/.forEach会使得它更难一些,因为您必须手动推送某些数组中的承诺(这不仅是丑陋的,而且也是错误的)。然而,如果你没有在循环内处理异步任务,你可以做任何你想做的事情。例如,无论

Promise.all(values.filter(syncPredicate).map(asyncFn)) 

Promise.all(promises).then((values) => values.filter(syncPredicate)) 

完全罚款。当你有一个异步过滤器谓词时,它确实变得有些复杂,我建议在这种情况下寻找一个promise实用程序库。

此外,您还必须认识到,从同步循环结构内启动的异步任务将并行运行。如果您打算按顺序运行它们(等待每次迭代),则应该尝试制定循环using a recursive structure

+0

在你看来,应该是以下功能重构?我具体指的是回调函数,延迟函数,以及该函数中的for循环: – thadeuszlay

+0

var getAllFooById = function(id){ var dfd = $ q.defer(); db.allDocs({include_docs:真},功能(ERR,响应){ 如果(ERR){ 的console.log(ERR); dfd.reject(ERR); }否则{ 变种fooArray = [] ; for(var i = 0; i thadeuszlay

+0

这是一个新问题吗?一个[回答](http://stackoverflow.com/help/self-answer)?我真的不能破译意见格式化代码,但它看起来像你使用的是[递延反模式](http://stackoverflow.com/q/23803743/1048572) – Bergi

相关问题