[英]AngularJS: Waiting for an asynchronous call
我無法理解AngularJS的承諾概念。
我有一個提供者:
var packingProvider = angular.module('packingProvider',[]);
packingProvider.provider('packingProvider',function(){
return{
$get: function($http){
return{
getPackings: function(){
$http.post('../sys/core/fetchPacking.php').then(function(promise){
var packings = promise.data;
return packings;
});
}
}
}
}
});
如您所見,這提供了一個方法getPackings()
,它將返回一個對象
現在,如果我在主應用程序中使用它來接收數據,則調用將是異步的,從而導致我必須“等待”數據的問題:
var packings = packingProvider.getPackings();
console.log(packings); // undefined
如果不將進程重構到我的主控制器中,我該怎么做?
嘗試
var packingProvider = angular.module('packingProvider',[]);
packingProvider.provider('packingProvider',function(){
return{
$get: function($http){
return{
getPackings: function(){
return $http.post('../sys/core/fetchPacking.php').then(function(response){
return response.data; // packings
});
}
}
}
}
});
然后
packingProvider.getPackings().then(function(packings){
console.log(packings);
});
主要思想:您需要從getPackings函數返回promise對象。 不確定你是否可以同步調用它,但這樣做幾乎絕對不是一個好主意。 此外,如果要在控制器上創建“填充”模型對象並用於雙向綁定,則可以安全地分配promise對象,Angular將在數據通過后立即解析:
$scope.packings = packingProvider.getPackings();
UPDATE
從1.2.0-rc.3開始,承諾解包已被棄用( https://github.com/angular/angular.js/blob/master/CHANGELOG.md#120-rc3-ferocious-twitch-2013-10-14 ),所以上面的代碼行不再導致雙向綁定。
當你認為它時,你的then
方法中的返回值不會返回; 它回來了。
在聲明中var packings = packingProvider.getPackings();
返回值是未定義的,因為從$http
返回的promise是異步的。 這意味着對$http.post
的調用發生, 沒有完成 ,然后你的函數返回。 在沒有返回任何內容的JS函數中返回undefined。 post
調用稍后完成並執行return packings;
它無處可歸。
getPackings
方法應該可以直接從$http.post
返回promise。 這樣,想要使用這種方法可以調用任何代碼, then
直接在承諾和所設置的值,它需要的方式。 在控制器中,您可以將該承諾直接分配給$scope
並在視圖中使用它。 這是一個很好的帖子,解釋了這個特殊的功能: http : //markdalgleish.com/2013/06/using-promises-in-angularjs-views/
順便說一句,看起來你在那里有一個冗長的服務聲明; 有什么理由不把它縮短到這樣的東西?
var module = angular.module('packing', []);
module.service('packing', function($http) {
return {
getPackings: function() {
return $http.post('../sys/core/fetchPacking.php');
}
};
});
我對AngularJS比較陌生,但我沒有看到所有輸入都有任何好處。 (=
有大量資源可以向您展示如何使用jQuery的Deferreds / Promises。 嘗試搜索那些,這可能會幫助您克服這個障礙。 Afaik,AngularJS承諾與jQuery承諾相同。
一個jQuery承諾使用這樣的東西:
var getPackings = function() { return $.get('../sys/core/fetchPacking.php'); };
var packings;
$.when(getPackings()).then(function(data){ packings = data; console.log(packings) });
請記住,jQuery ajax調用具有.done,.success等函數,它們將替換泛型Deferreds的.when()。then()函數。
在上面的jQuery方法中,您可以看到我們必須設置數據並將其輸出到.then()函數中,因為您無法保證異步過程在其他任何地方完成。 因此,理想情況下,您可以調用.then()函數中繼續處理的任何函數,如下所示:
$.when(myAsyncFunc()).then(myAppCanContinue(dataReturnedByAsyncFunc));
Angular將遵循相同的邏輯。 如果您了解上述內容,則應該更容易理解如何在Angular中實現此目的。 另外,請查看這篇提供簡單示例的文章: http : //markdalgleish.com/2013/06/using-promises-in-angularjs-views/
為了讓您的代碼正常工作,您需要執行以下操作:
packingProvider.provider('packingProvider',function(){
return{
$get: function($http){
return{
getPackings: function(){
return $http.post('../sys/core/fetchPacking.php');
}
}
}
}
});
var packings = packingProvider.getPackings();
packings.then(function(data) { console.log(data)});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.