我做到了,就像Bradley Braithwaite在他的博客中建议的那样:
app
.factory('searchService', ['$q', '$http', function($q, $http) {
var service = {};
service.search = function search(query) {
// We make use of Angular's $q library to create the deferred instance
var deferred = $q.defer();
$http
.get('http://localhost/v1?=q' + query)
.success(function(data) {
// The promise is resolved once the HTTP call is successful.
deferred.resolve(data);
})
.error(function(reason) {
// The promise is rejected if there is an error with the HTTP call.
deferred.reject(reason);
});
// The promise is returned to the caller
return deferred.promise;
};
return service;
}])
.controller('SearchController', ['$scope', 'searchService', function($scope, searchService) {
// The search service returns a promise API
searchService
.search($scope.query)
.then(function(data) {
// This is set when the promise is resolved.
$scope.results = data;
})
.catch(function(reason) {
// This is set in the event of an error.
$scope.error = 'There has been an error: ' + reason;
});
}])
关键点:
这是非常稳定和安全的,如果您有其他条件拒绝承诺,则可以始终在成功函数中过滤数据并deferred.reject(anotherReason)
以拒绝原因进行调用。
正如Ryan Vice在评论中所建议的那样,除非您对响应进行一些摆弄,否则这可能不会被视为有用。
因为从1.4开始不推荐使用success
和error
,所以最好使用常规的promise方法then
并catch
在这些方法中转换响应并返回转换后的响应的promise。
我在两种方法和第三种中间方法中都显示了相同的示例:
success
和error
方法(success
并error
返回HTTP响应的承诺,因此我们需要帮助$q
来返回数据的承诺):
function search(query) {
// We make use of Angular's $q library to create the deferred instance
var deferred = $q.defer();
$http.get('http://localhost/v1?=q' + query)
.success(function(data,status) {
// The promise is resolved once the HTTP call is successful.
deferred.resolve(data);
})
.error(function(reason,status) {
// The promise is rejected if there is an error with the HTTP call.
if(reason.error){
deferred.reject({text:reason.error, status:status});
}else{
//if we don't get any answers the proxy/api will probably be down
deferred.reject({text:'whatever', status:500});
}
});
// The promise is returned to the caller
return deferred.promise;
};
then
和catch
方法(由于抛出,这很难测试):
function search(query) {
var promise=$http.get('http://localhost/v1?=q' + query)
.then(function (response) {
// The promise is resolved once the HTTP call is successful.
return response.data;
},function(reason) {
// The promise is rejected if there is an error with the HTTP call.
if(reason.statusText){
throw reason;
}else{
//if we don't get any answers the proxy/api will probably be down
throw {statusText:'Call error', status:500};
}
});
return promise;
}
但是,有一个中途解决方案(通过这种方式,您可以避免使用throw
and,并且您可能需要使用它$q
来模拟测试中的promise行为):
function search(query) {
// We make use of Angular's $q library to create the deferred instance
var deferred = $q.defer();
$http.get('http://localhost/v1?=q' + query)
.then(function (response) {
// The promise is resolved once the HTTP call is successful.
deferred.resolve(response.data);
},function(reason) {
// The promise is rejected if there is an error with the HTTP call.
if(reason.statusText){
deferred.reject(reason);
}else{
//if we don't get any answers the proxy/api will probably be down
deferred.reject({statusText:'Call error', status:500});
}
});
// The promise is returned to the caller
return deferred.promise;
}
欢迎提出任何意见或更正。
success()
,error()
并finally()
与之结合catch()
?还是我必须使用then(successFunction, errorFunction).catch(exceotionHandling).then(cleanUp);