我有一个使用路由和视图的AngularJS应用。当加载特定视图并且控制器实例化时,我必须准备一些$scope
模型数据。这些数据可以由附属服务提供,或者当服务没有时,我会进行异步调用以从服务器获取它。
当我最终获得这些数据时,我必须稍微更改一下,然后将其放在我的$scope
上。
我认为这完全属于deferred / promise API。从服务获取数据是使用$resource
服务实例完成的,并且已经是一个承诺。我唯一的问题是将同步代码转换为延迟/承诺模式。
如何将我的同步代码处理更改为异步,以便我提供数据的函数始终返回一个承诺,在使用同步代码时会立即解决,并在一段时间后异步调用我的服务器?
var getData = function() {
var defer = $q.defer();
defer.promise
.then(function () {
// return cached item
return dataCacheService.get("dataKey");
})
.then(function(data) {
// cache returned data?
if (!data)
{
// no? get it from server returning a promise
return dataResource.get({
set: "models",
id: $routeParams.id
});
}
})
.then(function (data) {
// server returned data?
if (!!data) // <= PROBLEM!!! This is not null, but is a Resource with unresolved promise?
{
// yes? fine. manipulate it
delete data.details;
delete data.type.description;
$scope.lists.set(data.type);
return data;
}
// no data. sorry...
$scope.resetType();
})
// something went wrong
.catch($scope.resetType);
// initiate deferred execution
defer.resolve();
return defer.promise;
}
...
$scope.model = {
item: getData()
};
答案 0 :(得分:3)
您可以使您的服务始终返回承诺,如果数据可用,它将在REST调用后立即返回承诺。例如,您的服务可能如下所示:
var dataThatMayOrMayNotBeAvailable=null;
var getDataThatMayOrMayNotBeAvailable=function(){
var deferred = $q.defer();
if(dataThatMayOrMayNotBeAvailable){
deferred.resolve(dataThatMayOrMayNotBeAvailable);
}else{
$http({...}).success(function(data){
dataThatMayOrMayNotBeAvailable=data;
deferred.resolve(data);
});
}
return deferred.promise;
}
用法:
getDataThatMayOrMayNotBeAvailable().then(function(data){
console.log(data);
})