Eu faço isso como Bradley Braithwaite sugere em seu 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;
});
}])
Pontos chave:
A função de resolução se vincula à função .then em nosso controlador, ou seja, está tudo bem, então podemos manter nossa promessa e resolvê-la.
A função de rejeição é vinculada à função .catch em nosso controlador, ou seja, algo deu errado, então não podemos cumprir nossa promessa e precisamos rejeitá-la.
É bastante estável e seguro e se tiver outras condições para rejeitar a promessa pode sempre filtrar os seus dados na função de sucesso e ligar deferred.reject(anotherReason)
com o motivo da rejeição.
Como Ryan Vice sugeriu nos comentários , isso pode não ser visto como útil, a menos que você altere um pouco a resposta, por assim dizer.
Porque success
e error
são obsoletas desde 1.4 talvez seja melhor usar os métodos promessa regulares then
e catch
e transformar a resposta dentro desses métodos e retornar a promessa de que a resposta transformado.
Estou mostrando o mesmo exemplo com ambas as abordagens e uma terceira abordagem intermediária:
success
e error
abordagem ( success
e error
retornar uma promessa de uma resposta HTTP, portanto, precisamos da ajuda de $q
para retornar uma promessa de dados):
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
abordagem (isso é um pouco mais difícil de testar, por causa do lançamento):
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;
}
Porém, há uma solução intermediária (desta forma, você pode evitar o throw
e, de qualquer forma, provavelmente precisará usar $q
para simular o comportamento de promessa em seus testes):
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;
}
Qualquer tipo de comentários ou correções são bem-vindos.
success()
,error()
efinally()
combinado comcatch()
? Ou eu tenho que usarthen(successFunction, errorFunction).catch(exceotionHandling).then(cleanUp);