所以我要做的是我有一个带有一堆整数的数组,它代表一个id。我用id循环遍历数组。对于每个id,我进行一个ajax调用,它返回给我一个json然后我将这个json追加到我的结果数组中。我想保持结果数组的顺序与我进行ajax调用的顺序相同(即如果我按顺序'/ url / 1','url / 2',url / 3'对ID进行GET调用,我希望结果数组按照调用的顺序存储id 1,2和3的结果。这是我必须显示的内容的通用代码。
var ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var results = [];
var counter = 1;
ids.forEach(function(id) {
doAjax('GET', 'url' + id, function(returnValue) {
results.push(returnValue);
if (counter == 10) {
//dispatch some event
}
});
});
问题是结果数组的顺序每次都不同,因为ajax调用的异步性质。在有所有ajax调用之后,有什么方法可以确保结果的顺序保持不变(即结果= [来自id 1的结果,来自id 2的结果,来自id 3的结果,...来自id 10的结果) ]
答案 0 :(得分:2)
你应该让doAjax
返回promise,将数组的每个元素映射到一个promise并将promises数组传递给Promise.all
。结果数组Promise.all
“返回”与输入数组的顺序相同。
Promise.all(ids.map(id => doAjax('GET', 'url' + id)).then(results => {
//dispatch some event
});
答案 1 :(得分:1)
如果您使用promises,这是一个好主意,出于多种原因,您将按照创建它们的顺序获得结果。
首先将每个AJAX调用包装在一个promise中,然后使用调用结果解析它。使用map()
代替forEach()
来传播包含所有承诺的数组:
var promises = ids.map(function(id) {
return new Promise(function(resolve) {
doAjax('GET', 'url' + id, function(returnValue) {
resolve(returnValue);
});
});
});
然后你可以制作一个单一的promise,当数组中的所有promise都已解析时解析,对此的回调将传递一个数组,其中所有结果都按正确的顺序排列:
Promise.all(promises).then(function(promiseResults) {
// The promiseResults array here will contain the results of all AJAX calls in the order you created them
});
正如您所看到的,在使用承诺时,您不需要counter
或声明的results
变量。
这些都可以更加整齐有效地编写,但我的例子有望帮助你理解。
答案 2 :(得分:0)
你应该让每个id都是这样的对象:
var ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(function(id) {
return {id: id};
});
现在,不要在doAjax
中引用ID,而是使用id.id
。
您可以简单地将新属性添加到id
对象,而不是将结果推送到单独的数组中,如下所示:
id.result = returnValue;
如果您愿意,可以执行另一个地图操作来创建results
数组:
var results = ids.map(function(id) {
return id.result;
});