Ich mache es so, wie Bradley Braithwaite es in seinem Blog vorschlägt :
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;
});
}])
Wichtige Punkte:
Die Auflösungsfunktion ist mit der .then-Funktion in unserem Controller verknüpft, dh alles ist in Ordnung, sodass wir unser Versprechen halten und es auflösen können.
Die Ablehnungsfunktion ist mit der .catch-Funktion in unserem Controller verknüpft, dh es ist ein Fehler aufgetreten, sodass wir unser Versprechen nicht einhalten können und es ablehnen müssen.
Es ist ziemlich stabil und sicher, und wenn Sie andere Bedingungen haben, um das Versprechen abzulehnen, können Sie Ihre Daten jederzeit in der Erfolgsfunktion filtern und deferred.reject(anotherReason)
mit dem Grund der Ablehnung anrufen .
Wie Ryan Vice in den Kommentaren angedeutet hat , kann dies nicht als nützlich angesehen werden, es sei denn, Sie spielen sozusagen ein bisschen mit der Antwort herum.
Weil success
und error
seit 1.4 veraltet sind, ist es vielleicht besser, die regulären Versprechensmethoden zu verwenden then
und catch
die Antwort innerhalb dieser Methoden zu transformieren und das Versprechen dieser transformierten Antwort zurückzugeben.
Ich zeige das gleiche Beispiel mit beiden Ansätzen und einem dritten Zwischenansatz:
success
und error
Ansatz ( success
und error
ein Versprechen einer HTTP-Antwort zurückgeben, daher benötigen wir die Hilfe $q
, um ein Versprechen von Daten zurückzugeben):
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
und catch
Annäherung (dies ist aufgrund des Wurfs etwas schwieriger zu testen):
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;
}
Es gibt jedoch eine Lösung auf halbem Weg (auf diese Weise können Sie das vermeiden throw
und müssen es wahrscheinlich verwenden $q
, um das Versprechen in Ihren Tests zu verspotten):
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;
}
Kommentare oder Korrekturen jeglicher Art sind willkommen.
success()
,error()
undfinally()
kombiniert mitcatch()
? Oder muss ich verwendenthen(successFunction, errorFunction).catch(exceotionHandling).then(cleanUp);