[英]Async request into for loop angular.js
我有一個數組,我需要逐個通過http post請求將數組的值發送到webservice。 對於node.js,我正在使用“async”包為ex: async.eachSeries
做得很好,我怎么能為angular.js做同樣的事情,我的正常異步代碼;
//this code sends all queries of array (maybe 5.000 request at same time , it is hard to process for webservice :=) ) at same time and wait for all responses.
//it works but actually for me , responses should wait others at end of loop should work one by one
//like async.eachSeries module!
for (var i = 0; i < myArr.lenght; i++) {
(function (i) {
var data = {
"myQuery": myArr[i].query
};
$http.post("/myServiceUrl", data).success(function (result) {
console.log(result);
});
})(i);
}
Matt Way和Chris L都回答正確 ,您可以調查Chris的答案,以了解for循環中異步同步函數。
您可以通過將promises鏈接在一起來使用$q
來創建類似的需求。 例如:
var chain = $q.when();
angular.forEach(myArr, function(item){
chain = chain.then(function(){
var data = {
myQuery: item.query
};
return $http.post('/myServiceUrl', data).success(function(result){
console.log(result);
});
});
});
// the final chain object will resolve once all the posts have completed.
chain.then(function(){
console.log('all done!');
});
基本上,只要前一個承諾完成,您就會運行下一個承諾。 這里強調的是,根據您的問題,每個請求都將等到上一個請求完成。
如果我正確理解你的問題。 您希望以同步方式運行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時遇到的問題。當我設置一個小提琴時。 希望這有助於說明我為什么這樣做。
https://jsfiddle.net/chrislewispac/6atp3w8o/
使用Matt的答案中的以下代碼:
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的同一階段還有很多其他人)。
function logResultFromWebService(value)
{
$http.post("/myServiceUrl", value).success(console.log);
}
angular.forEach(myArray, logResultFromWebService);
如果訂單與發送它們無關緊要
var items = [/* your array */];
var promises = [];
angular.forEach(items, function(value, key){
var promise = $http.post("/myServiceUrl", { "myQuery": value.query });
promises.push(promise);
});
return $q.all(promises);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.