如果我正确理解你的问题。您希望以同步方式运行for循环,以便只有在前一次迭代完成后才会发生下一次迭代。为此,您可以使用同步循环/回调。特别是如果订单很重要。
var syncLoop = function (iterations, process, exit) {
var index = 0,
done = false,
shouldExit = false;
var loop = {
next: function() {
if (done) {
if (shouldExit && exit) {
return exit(); // Exit if we're done
}
}
// If we're not finished
if (index < iterations) {
index++; // Increment our index
process(loop); // Run our process, pass in the loop
// Otherwise we're done
} else {
done = true; // Make sure we say we're done
if (exit) exit(); // Call the callback on exit
}
},
iteration: function() {
return index - 1; // Return the loop number we're on
},
break: function (end) {
done = true; // End the loop
shouldExit = end; // Passing end as true means we still call the exit callback
}
};
console.log('running first time');
loop.next();
return loop;
}
为了您的具体实现:
syncLoop(myArray.length, function (loop) {
var index = loop.iteration();
var data = {
"myQuery": myArray[index].query
};
$http.post("/myServiceUrl", data).success(function (result) {
console.log(result);
loop.next();
});
}, function() {
console.log('done');
});
如果你打算做一些与数据一次返回(如执行计算),你可以用这个方法做,因为你将返回的数据一个特定的顺序。
我在我构建的统计计算web应用程序中实现了类似的东西。
编辑:
为了说明我使用的时候$ q.when我已成立了一个小提琴有问题。希望这将有助于说明我为什么按照我的方式做到了这一点。
https://jsfiddle.net/chrislewispac/6atp3w8o/
从马特的答案使用下面的代码:
var chain = $q.when(promise.getResult());
angular.forEach(myArr, function (item) {
chain = chain.then(function() {
$rootScope.status = item;
console.log(item);
});
});
// the final chain object will resolve once all the posts have completed.
chain.then(function() {
console.log('all done!');
});
这琴是我的解决方案的一个例子:
https://jsfiddle.net/chrislewispac/Lgwteone/3/
的$ Q版进行比较,以我的版。查看控制台并想象那些交付给用户界面的用户在过程中进行用户干预和/或对顺序退货执行统计操作。
你会发现它不会在控制台或Matt的回答中的视图中依次给出数字1,2,3,4等。它'批'的反应,然后返回它们。因此,如果根据步骤2中的响应不执行步骤3,则至少在提供的答案中不存在突破或显式控制此处的同步操作的方式。这在尝试执行顺序计算和/或允许用户控制断点等时提出了重大问题。
现在,我正在挖掘$ q库和Q库以查看是否有更多这个问题的优雅解决方案。但是,我的解决方案按照要求工作,并且非常明确,它允许我将该函数放置在服务中,并按照我的意愿操作某些用例,因为我完全理解它在做什么。对我而言,这比使用库更重要(至少在我作为程序员开发的这个阶段,我确信在StackOverflow的同一阶段还有很多其他人)。
命令是否重要? – Teliren
你可以在浏览器中使用'async'软件包,使用'$ http'。唯一的问题是如果你想用你的结果更新'$ scope',那么你可能需要使用'$ scope。$ apply'或'$ timeout'(没有可选的延迟) – Jack