如何使用以任意顺序返回的promise来存储for循环的计数?

时间:2014-08-15 10:38:52

标签: javascript angularjs promise angular-promise

我正在制作一系列http请求,我需要在返回时将结果存档到列表对象中。我使用有角度的承诺。

因为promises只在for循环结束后解析,所以它们都被归入列表的最后一个索引。

for (var i = 0;i < list.length; i+=1) {
    Promise.do(action).then(function(result) {
        list[i] //i is always at last index because the for loop has already completed
    }
}

5 个答案:

答案 0 :(得分:3)

Bind索引作为接收结果的函数的参数:

for (var i = 0;i < list.length; i+=1) {
    Promise.do(action).then((function(index, result) {
        list[index]
    }).bind(null, i));
}

答案 1 :(得分:2)

不要使用标准循环。请改用Array.forEach。每次调用提供给forEach的函数时,你都会得到一个新的闭包,因此我会给你一个新的副本

答案 2 :(得分:1)

我会尝试使用$q.all

var promises = [];

for (var i = 0; i < list.length; i += 1) {
    promises.push(Promise.do(action));
}

$q.all(promises).then(function(results) {
    console.log(results);
});

来自文档:

  

返回将使用数组/散列解析的单个promise   值,每个值对应于相同索引/键的promise   在promises数组/哈希中。如果任何承诺通过a解决   拒绝,由此产生的承诺将被拒绝   拒绝价值。

答案 3 :(得分:0)

同意Bergi的评论,这看起来像臭名昭着的循环问题。但是,我在注意到Bergi的评论之前输入了我的答案,所以这里有几个解决方案:

for (var i = 0;i < list.length; i+=1) {
    var callback = function(result) {
        list[arguments.callee.i]...
    }
    callback.i = i;
    Promise.do(action).then(callback);
}

OR:

for (var i = 0;i < list.length; i+=1) {
    var callback = function(n) {
        return function(result) {
            list[n]...
        };
    }(i);
    Promise.do(action).then(callback);
}

答案 4 :(得分:-1)

您可以在Promise.then块中调用下一轮'循环',如下所示:

function do_thing(i) {
    // Are we finished? If so, return.
    if (i == list.length) return;
    Promise.do(action).then(function(result) {
        list[i]
        // Do the next thing, only once the previous thing completed.
        do_thing(i+1)
    }
}
// Start at the first thing.
do_thing(0)

问题在于你失去了发生并行异步调用的好处 - 一切都被序列化 - 所以它会慢一些。使用jQuery承诺,您可以将索引附加到promise对象...这是否可以使用angular?

for (var i = 0;i < list.length; i+=1) {
    var p = Promise.do(action)
    p.index = i
    p.then(function(result) {
         // this.index is the value of i so do...
         list[this.index] 
    }
}

这是一个小提示,显示jQuery风格:http://jsfiddle.net/sifriday/0v6vr77y/