我正在尝试在控制器中调用服务方法。这是我的代码。 ROAService.js:
return{
loadROAValues:function(userId,roaId){
var params=JSON.stringify({userId:userId,roaId:roaId});
var promise =$http.post(url+'/'+'getROAItems',params).success(function(data) {
roaDetails = data;
$log.debug("values in service class");
$log.debug("values in ROA");
$log.debug(roaDetails.id);
return roaDetails
})
.error(function(data){
roaDetails = 'error';
return roaDetails;
});
return promise;
}
}
在控制器ROA控制器中:
$scope.getCurrentROA = function(roaObj){
currentROA = ROAService.loadROAValues($scope.getMemberId(),roaObj.id).then(function(response) {
console.log(response);
}).catch(function(response) {
console.log("failure", response);
});
$log.debug("ROA id in controller class is:"+currentROA.id);
};
我得到以下输出:
ROA id in controller class is :undefined
values in service class
values in ROA
386.
来自控制器的ROA id在服务呼叫完成之前打印。它可能是竞争条件。如何保持控制器等到承诺返回?如何解决这种竞争状况?
答案 0 :(得分:0)
如何保持控制器等到承诺返回?
代码存在两个问题。
服务工厂功能正在.success
方法中返回数据,但.success
方法会忽略返回值。
控制器需要返回数据,但服务功能会返回承诺而不是数据。
另一个可能的问题是代码在定义服务工厂时定义服务类。很难从问题中判断出是否是这种情况,所以在我的例子中我会明确说明。
angular.module("myApp",[]);
angular.module("myApp").factory("ROAService", function($http) {
function loadROAValues(userId,roaId){
var params = JSON.stringify({userId:userId,roaId:roaId});
var promise = $http.post(url+'/'+'getROAItems',params);
//chain from .then method
promise.then( function(response) {
var roaDetails = response.data;
$log.debug("values in service class");
$log.debug("values in ROA");
$log.debug(roaDetails.id);
//return data for chaining
return roaDetails;
//process error in .catch method
}).catch( function(error){
var roaDetails = 'error:' + error.status;
//throw errors for chaining
throw roaDetails;
});
//return promise for chaining
return promise;
};
//return service function from factory
return { loadROAValues: loadROAValues };
});
除了.success
和.error
方法忽略返回值并返回旧承诺的问题之外,这些方法弃用即可。有关详细信息,请参阅AngularJS $http Service API Reference -- deprecation notice。
angular.module("myApp").controller("myController",
['$scope', 'ROAService', function ($scope, ROAService) {
//function returns a promise
$scope.getCurrentROA = function(memberId, roaObj){
//service function returns promise
var promiseFromROA =
ROAService.loadROAValues(memberId, roaObj.id);
//chain from promise
promiseFromROA.then( function(roaDetails) {
//$q service waits for promise to resolve
//get values here
$log.debug("ROA id is:"+roaDetails.id);
//return for further chaining
return roaDetails;
}).catch ( function (error) {
//process chained error
console.log("failure: " + error);
//throw for further chaining
throw error;
});
//return promise for further chaining
return promiseFromROA;
};
}]
);
功能编程的经验法则是始终返回。通过返回和链接来利用承诺的力量。
有关链接的更多信息,请参阅AngularJS $q Service API Reference -- chaining promises。