Lo faccio come suggerisce Bradley Braithwaite nel suo blog :
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;
});
}])
Punti chiave:
La funzione di risoluzione si collega alla funzione .then nel nostro controller, cioè va tutto bene, quindi possiamo mantenere la nostra promessa e risolverla.
La funzione di rifiuto si collega alla funzione .catch nel nostro controller, cioè qualcosa è andato storto, quindi non possiamo mantenere la nostra promessa e dobbiamo rifiutarla.
È abbastanza stabile e sicuro e se hai altre condizioni per rifiutare la promessa puoi sempre filtrare i tuoi dati nella funzione di successo e chiamare deferred.reject(anotherReason)
con il motivo del rifiuto.
Come ha suggerito Ryan Vice nei commenti , questo potrebbe non essere visto come utile a meno che non giocherelli un po 'con la risposta, per così dire.
Perché success
e error
sono deprecati dal 1,4 forse è meglio usare i metodi promessa regolari then
ed catch
e trasformare la risposta all'interno di tali metodi e restituire la promessa di tale risposta trasformata.
Sto mostrando lo stesso esempio con entrambi gli approcci e un terzo approccio intermedio:
success
e error
approccio ( success
e error
restituire una promessa di una risposta HTTP, quindi abbiamo bisogno dell'aiuto di $q
per restituire una promessa di dati):
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
e catch
approccio (questo è un po 'più difficile da testare, a causa del lancio):
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;
}
C'è una soluzione a metà però (in questo modo puoi evitare il throw
e comunque probabilmente dovrai usarlo $q
per deridere il comportamento della promessa nei tuoi test):
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;
}
Qualsiasi tipo di commento o correzione è il benvenuto.
success()
,error()
efinally()
in combinazione concatch()
? Oppure devo usarethen(successFunction, errorFunction).catch(exceotionHandling).then(cleanUp);