angularjs如何在循環裡面請求數據並正確賦值?

我目前有一個需求如下,需要在一個循環裡面請求數據,然而$http.jsonp()這個是非同步請求,如果我循環10次,最後一個響應回來的數據會被賦值到i=9的時候,比如下面的代碼,i列印10次出來全部是9,然後如果在裡面進行操作,也只有最後一個相應能對最後一次循環進行操作。

問題是 angularjs 有沒有同步請求? 或者遇到這樣的情況有沒有什麼好的處理辦法?

for(var i=0; i &< 10; i++){

var data = new Object();

$http.jsonp(url).success(function(res){

console.log(i);

});

}


千萬不要在循環裡面調用API獲取數據,且不說有解決辦法,這種做法就是錯誤的,你應該先把所有的數據獲取回來,然後賦值給一個數組,頁面 ng-repeat 這個數組即可,要減少遠程請求。

非要這樣做可以這樣

var data = [10];
for(var i = 0; i &< 10; i++){ (function(i){ $http.jsonp(url).success(function(res){ data[i] = res; }); })(i); }

原理是:for循環中定義的變數i是在當前整個上下文的,循環結束後這個i就是9了,當非同步獲取數據回來後循環已經結束,i已經是9,ES6中的let就是解決這個問題的,每次循環都會創建獨立的變數上下文,ES5中解決方法就是加個匿名函數,這樣就會在匿名函數中創建獨立的上下文。


AngularJS的$http 確實是非同步的

但是你可以用deferredpromise 來解決。

function foo(){
var deferred = $q.defer();

$http.xxx({})
.success(function(data, status, headers, config) {
deferred.resolve(data);
})
.error(function(data, status, headers, config) {
deferred.reject(data);
});
return deferred.promise;
}

然後通過調用foo()取值。

var promise = foo();
promise.then(function(data) {
var something = data;
});


這個問題和angular沒什麼直接關係,在循環里賦值用閉包即可。


用原生js閉包就可以了。


推薦閱讀:

一個非同步函數是不是內核會單獨開一個線程來運行?

TAG:非同步IO | AngularJS |