Я пишу службу, которая будет извлекать данные асинхронно ($ http или $resource). Я могу скрыть тот факт, что он асинхронен, возвращая массив, который изначально будет пустым, но в конечном итоге он будет заселен:
.factory('NewsfeedService1', ['$http', function($http) {
var posts = [];
var server_queried = false;
return {
posts: function() {
if(!server_queried) {
$http.get('json1.txt').success(
function(data) {
server_queried = true;
angular.copy(data, posts);
});
}
return posts;
}
};
}])
.controller('Ctrl1', ['$scope','NewsfeedService1',
function($scope, NewsfeedService1) {
$scope.posts = NewsfeedService1.posts();
}])
Или я могу разоблачить асинхронность, возвращая обещание:
.factory('NewsfeedService2', ['$http', function($http) {
var posts = [];
var server_queried = false;
var promise;
return {
posts_async: function() {
if(!promise || !server_queried) {
promise = $http.get('json2.txt').then(
function(response) {
server_queried = true;
posts = response.data;
return posts;
});
}
return promise;
}
};
}])
.controller('Ctrl2', ['$scope','NewsfeedService2',
function($scope, NewsfeedService2) {
NewsfeedService2.posts_async().then(
function(posts) {
$scope.posts = posts;
});
// or take advantage of the fact that $q promises are
// recognized by Angular templating engine:
// (note that Peter and Pawel AngularJS book recommends against this, p. 100)
$scope.posts2 = NewsfeedService2.posts_async();
}]);
(Plunker - если кто-то хочет играть с этими двумя реализациями.)
Одним из потенциальных преимуществ разоблачения асихотроны было бы то, что я могу справиться с ошибками в контроллере, добавив обработчик ошибок в метод then()
. Тем не менее, я, скорее всего, поймаю и столкнусь с ошибками $http в общесистемном interceptor.
Итак, когда должна раскрываться асинхронность службы?