Robię to tak, jak sugeruje Bradley Braithwaite na swoim blogu :
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;
});
}])
Kluczowe punkty:
Funkcja rozwiązywania łączy się z funkcją .then w naszym kontrolerze, czyli wszystko jest w porządku, więc możemy dotrzymać obietnicy i rozwiązać ją.
Funkcja odrzucania łączy się z funkcją .catch w naszym kontrolerze, czyli coś poszło nie tak, więc nie możemy dotrzymać obietnicy i musimy ją odrzucić.
Jest dość stabilny i bezpieczny, a jeśli masz inne warunki, aby odrzucić obietnicę, zawsze możesz filtrować swoje dane w funkcji sukcesu i dzwonić deferred.reject(anotherReason)
z przyczyną odrzucenia.
Jak zasugerował Ryan Vice w komentarzach , może to nie być postrzegane jako przydatne, chyba że będziesz trochę bawić się odpowiedzią, że tak powiem.
Ponieważ success
i error
są przestarzałe od wersji 1.4, być może lepiej jest użyć zwykłych metod obietnicy then
icatch
i przekształcenia odpowiedzi w tych metodach i powrócić obietnicę tej przekształconej odpowiedzi.
Pokazuję ten sam przykład z obydwoma podejściami i trzecim podejściem pośrednim:
success
i error
podejdź ( success
i error
zwróć obietnicę odpowiedzi HTTP, więc potrzebujemy pomocy, $q
aby zwrócić obietnicę danych):
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
i catch
podejście (jest to trochę trudniejsze do przetestowania ze względu na rzut):
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;
}
Istnieje jednak rozwiązanie połowiczne (w ten sposób możesz uniknąć, throw
a mimo to prawdopodobnie będziesz musiał użyć, $q
aby kpić z obiecującego zachowania w swoich testach):
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;
}
Wszelkie uwagi i poprawki są mile widziane.
success()
,error()
afinally()
w połączeniu zcatch()
? Czy też muszę użyćthen(successFunction, errorFunction).catch(exceotionHandling).then(cleanUp);