gpt4 book ai didi

angularjs - 服务应该暴露它们的异步性吗?

转载 作者:行者123 更新时间:2023-12-03 13:31:50 24 4
gpt4 key购买 nike

我正在编写一个将异步检索数据的服务($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();
}])

或者我可以通过返回一个 promise 来暴露异步性:

.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's templating engine:
// (note that Peter and Pawel's AngularJS book recommends against this, p. 100)
$scope.posts2 = NewsfeedService2.posts_async();
}]);

( Plunker - 如果有人想玩弄上述两种实现。)

暴露异步性的一个潜在优势是我可以通过向 then() 添加错误处理程序来处理 Controller 中的错误。方法。但是,我可能会在应用程序范围内捕获和处理 $http 错误 interceptor .

那么,什么时候应该暴露服务的异步性呢?

最佳答案

我的猜测是你会在这道栅栏的两边找到人。就个人而言,我认为您应该始终公开库或函数的异步性(或者更准确地说:我认为您永远不应该隐藏库或函数的异步性)。主要原因是透明度;例如,这行得通吗?

app.controller('MyController', function(NewsfeedService) {
$scope.posts = NewsfeedService.posts();
doSomethingWithPosts($scope.posts); // <-- will this work?
});

如果您使用第一种方法(例如 $resource ),则不会,即使 $scope.posts在技​​术上是一个数组。如果 doSomethingWithPosts有它自己的异步操作,你最终可能会遇到竞争条件。相反,无论如何您都必须使用异步代码:

app.controller('MyController', function(NewsfeedService) {
$scope.posts = NewsfeedService.posts(function() {
doSomethingWithPosts($scope.posts);
});
});

(当然,您可以让回调接受 posts 作为参数,但我仍然认为它令人困惑且不标准。)

幸运的是,我们有 Promise,而 Promise 的目的就是代表操作的 future 值(value)。此外,由于使用 Angular 的 $q 创建的 Promise库可以绑定(bind)到 View ,这没有错:

app.controller('MyController', function(NewsfeedService) {
$scope.posts = NewsfeedService.posts();
// $scope.posts is a promise, but when it resolves
// the AngularJS view will work as intended.
});

[更新:您不能再将 Promise 直接绑定(bind)到 View ;您必须等待 promise 得到解决并手动分配范围属性。]

顺便说一句, Restangular$resource 的流行替代品, 使用 Promise 和 AngularJS 自己的 $resource将在 1.2 中支持它们(他们可能已经在最新的 1.1.x 中支持它们)。

关于angularjs - 服务应该暴露它们的异步性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17416599/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com