Я роблю це так, як пропонує Бредлі Брейтвайт у своєму блозі :
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;
});
}])
Ключові моменти:
Функція дозволу посилається на функцію .then в нашому контролері, тобто все добре, тому ми можемо виконати свою обіцянку і вирішити її.
Функція відхилення посилається на функцію .catch в нашому контролері, тобто щось пішло не так, тому ми не можемо дотримати обіцянку і потрібно її відхилити.
Це досить стабільно і безпечно, і якщо у вас є інші умови відхилити обіцянку, ви завжди можете відфільтрувати свої дані у функції успіху та зателефонувати deferred.reject(anotherReason)
з причиною відхилення.
Як запропонував Райан Віце в коментарях , це може не вважатися корисним, якщо ви трохи не поспішаєте з відповіддю, так би мовити.
Тому що success
і error
застаріли з 1.4, можливо, краще використовувати методи звичайних обіцянок then
іcatch
і перетворити відповідь в цих методах і повернути обіцянку цього трансформованого відповіді.
Я показую той самий приклад з обома підходами та третім підходом між ними:
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
і все одно вам, мабуть, потрібно буде скористатися, $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)
.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);