我想创建一个角度服务,在“启动”时抓取数据并构建一个在应用程序生命周期内不会改变的数组。我不想返回http请求的承诺。缓存结果仍然会导致'someExpensiveFunctionCall'的成本。处理这种情况的最佳方法是什么,可以保证服务将填充结果,并可以在控制器和/或其他服务中使用。
angular.module('app')
.service('MyService', function($http, defaults) {
var result = [];
$http.get('/some/url').then(function(data) {
if(angular.isDefined(data)) {
_.forEach(data, function(item) {
result.push(someExpensiveFunctionCall(item.value));
});
} else {
result = angular.copy(defaults.defaultResult);
}
});
return {
result: result
};
})
.controller(function(MyService) {
var someData = MyService.result;
})
.service(function(MyService) {
var someData = MyService.result;
});
答案 0 :(得分:1)
我不想退回http请求的承诺。
好像你想要做一些异步的事情;同步。如果没有某种回调,承诺,同步XHR或其他机制,这将无法正常工作。
知道我们可以评估一些选项。 (按照最实际的顺序)
使用路由器resolve
属性。这将在实例化控制器之前完成一些承诺返回操作。它(在ui-router
和ngRoute
中)表示承诺的结果将以指定的密钥名称注入控制器。
使用承诺。
(手动称为#1)
.factory('MyService',function($http,defaults){
var ret = {result: []};
ret.promise = $http.get('url').then(function(data){
if(angular.isDefined(data)){
_.forEach(data,function(item){
ret.result.push(someExpensiveFunctionCall(item.value));
});
}else{
_.forEach(angular.copy(defaults.defaultResult),function(val){
ret.result.push(val);
});
}
return ret;
});
return ret;
})
.controller('MyCtrl',function(MyService){
MyService.promise.then(myCtrl);
function myCtrl(){
var result = MyService.result
}
})
result
。但是,使用视图绑定,过滤器和交互来调用作用于数据的作用域函数。由于promise的解析将调用摘要周期。数据到达时,您的视图将呈现。如果data
恰好未定义,则代码中存在错误。您通过将其设置为默认值的副本来取消引用result
。
所以对MyService.result
的所有引用都将是一个空数组,而不是默认值。
为了保持引用,我会循环使用默认值,并使用result
将其添加到result.push
。
希望这有帮助!