我无法理解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
如果不将进程重构到我的主控制器中,我该怎么做?
答案 0 :(得分:7)
尝试
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();
<强>更新强>
从1.2.0-rc.3开始,承诺解包已被弃用(https://github.com/angular/angular.js/blob/master/CHANGELOG.md#120-rc3-ferocious-twitch-2013-10-14),因此上面的代码行不再导致双向绑定。
答案 1 :(得分:7)
您认为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比较陌生,但我没有看到所有输入都有任何好处。 (=
答案 2 :(得分:1)
有大量资源可以向您展示如何在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)});