Javascript 角度服务中的$http承诺
我有一个角度服务承诺的问题。我有一个带有方法Javascript 角度服务中的$http承诺,javascript,angularjs,Javascript,Angularjs,我有一个角度服务承诺的问题。我有一个带有方法getArea的服务,该方法应该返回服务区域的名称。该服务从API获取服务区域。当getArea获取服务区域时,它会找到请求区域的名称,并应返回该名称。然而,我的代码不起作用——我进入了一个无限循环。我想我误解了如何使用承诺 供应商服务: var servicePromise; var getServices = function(){ if( !servicePromise ){ servicePromise = $http.
getArea
的服务,该方法应该返回服务区域的名称。该服务从API获取服务区域。当getArea
获取服务区域时,它会找到请求区域的名称,并应返回该名称。然而,我的代码不起作用——我进入了一个无限循环。我想我误解了如何使用承诺
供应商服务:
var servicePromise;
var getServices = function(){
if( !servicePromise ){
servicePromise = $http.get('/api/services')
.then(function(res){
return res.data.data;
});
}
return servicePromise;
};
var myService = {
getServices : getServices,
getArea : function(questionnaireId){
getServices().then(function(services){
// ...
return "hello world";
});
}
};
return myService;
$scope.supplierService = SupplierService;
<div>
<b>Area:</b> {{ supplierService.getArea(r.questionnaireId) }}
</div
控制器:
var servicePromise;
var getServices = function(){
if( !servicePromise ){
servicePromise = $http.get('/api/services')
.then(function(res){
return res.data.data;
});
}
return servicePromise;
};
var myService = {
getServices : getServices,
getArea : function(questionnaireId){
getServices().then(function(services){
// ...
return "hello world";
});
}
};
return myService;
$scope.supplierService = SupplierService;
<div>
<b>Area:</b> {{ supplierService.getArea(r.questionnaireId) }}
</div
查看:
var servicePromise;
var getServices = function(){
if( !servicePromise ){
servicePromise = $http.get('/api/services')
.then(function(res){
return res.data.data;
});
}
return servicePromise;
};
var myService = {
getServices : getServices,
getArea : function(questionnaireId){
getServices().then(function(services){
// ...
return "hello world";
});
}
};
return myService;
$scope.supplierService = SupplierService;
<div>
<b>Area:</b> {{ supplierService.getArea(r.questionnaireId) }}
</div
因此,我猜问题出在getArea
方法中
更新2:这个答案启发了我。我想缓存结果
更新3:这里有一个。如果尝试从视图访问supplierService.getArea(100),浏览器将不会响应 您的服务应该更像这样:
SupplierService.getServices().then(function(d){
$scope.services = d;
});
var getServices = function(){
var deferred = $q.deferred();
$http.get('/api/services')
.then(function(res){
deferred.resolve(res.data)
});
return deferred.promise;
};
请注意,在创建延迟调用时,必须返回deferred.promise(实际承诺),然后在异步调用返回时,必须根据需要调用deferred.resolve或deferred.rejected(分别触发成功或错误函数)
小补充我有一个plunkr,展示了从服务获取数据到控制器的几种方法,因为这是开发人员进入应用程序的常见问题
这不是绝对的最佳实践,因为我试图使其尽可能简单,但基本上展示了三种不同的“共享”数据的方法请记住,其中一些方法依赖于angular.copy,这意味着存储数据的服务的属性必须是对象或数组(由于无法共享引用,基元类型将不起作用)
以下是包含函数内联的重写:
var myService = {
var dataLoaded = false;
var data = {}; //or = [];
getServices : function(){
var deferred = $q.defer();
if( !dataLoaded ){
$http.get('/api/services').then(function(res){
angular.copy(res.data, myService.data);
deferred.resolve(myService.data);
}, function(err){
deferred.reject("Something bad happened in the request");
});
}
else
{
deferred.resolve(myService.data);
}
return deferred.promise;
}
};
return myService;
为了解释,我使用$q服务创建了一个新的承诺,您需要将其注入到服务函数中。这允许我使用我已有的数据来解析该承诺,或者调用服务并解析该数据,但在这两种情况下,当使用该服务时,都假定您只会得到一个承诺,并因此被撤销使用异步操作进行标记。如果要加载多个数据集,可以使用对象来存储标记,而不是使用单个布尔值。我认为如果返回$http回调
//$http.get('/someUrl').success(successCallback);
var getServices = function(){
return $http.get('/api/services');
};
getServices.success(function(services){
// ...
return "hello world";
});
}
+1$q服务,Angular的精益承诺服务,将被注入。您当然可以返回$http.get('/api/services'),因为它已经是一个承诺。很好的一点是,我倾向于这样做,并使用一个对象来检查我是否已经加载了数据(为我将在服务中进行的每个服务调用存储一个属性,以了解数据是否已加载),我想我已经习惯了“显式”地进行此操作但是正如您所说,使用get返回的HttpPromise也是一个很好的解决方案。
getArea
方法中的问题不是吗?我实际上也返回了getServices方法,当异步调用返回时,我在控制器中得到了服务。@Sweedo不确定这里还缺少了什么,您是否仍然遇到了问题最后一个版本的代码,你能发布一个plunkr或JSFIDLE来显示你的问题吗?@shaunhusain我已经发布了一个plunkr,以及我的代码版本。它表明我的getServices()
可以工作,但getArea
不能。