我在StackOverflow上看到了人们建议为AngularJS服务提供回调函数的答案。
app.controller('tokenCtrl', function($scope, tokenService) {
tokenService.getTokens(function callbackFn(tokens) {
$scope.tokens = tokens;
});
});
app.factory('tokenService', function($http) {
var getTokens = function(callbackFn) {
$http.get('/api/tokens').then (function onFulfilled(response) {
callbackFn(response.data);
});
};
return {
getTokens: getTokens
};
});
在我看来,这是一种反模式。 $http
服务返回promise并且.then
方法执行回调函数感觉就像是一个不健康的控制反转。
一个重新分解这样的代码如何解释为什么原始方式不是一个好主意?
答案 0 :(得分:7)
您应该将其更改为
var getTokens = function() {
return $http.get('/api/tokens');
};
然后,在其他模块中使用
yourModule.getTokens()
.then(function(response) {
// handle it
});
至于为什么它是反模式,我要说,首先,它不允许你进一步链接你的成功/失败处理程序方法。其次,它处理从调用者模块到被调用模块的响应处理的控制(这里可能不是非常重要,但它仍然施加相同的控制反转)。最后,你向你的代码库添加了promises的概念,对于一些团队成员来说可能不那么容易理解,但是然后使用promises作为回调,所以这真的没有意义。
答案 1 :(得分:1)
代码可以重新计算如下:
app.controller('tokenCtrl', function($scope, tokenService) {
tokenService.getTokens.then ( callbackFn(tokens) {
$scope.tokens = tokens;
});
});
app.factory('tokenService', function($http) {
var getTokens = function() {
//return promise
return $http.get('/api/tokens').then (function onFulfilled(response) {
//return tokens
return response.data;
}
);
};
return {
getTokens: getTokens
};
});
通过让服务返回承诺,并使用承诺的.then
方法,可以实现相同的功能,具有以下优点:
承诺可以保存并用于链接。
可以保存并使用承诺,以避免重复相同的$http
电话。
保留错误信息,可以使用.catch
方法检索错误信息。
承诺可以转发给其他客户。