Bradley Braithwaiteが彼のブログで提案しているように私はそれをしています:
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;
});
}])
キーポイント:
それは非常に安定していて安全であり、約束を拒否する他の条件がある場合は、常に成功関数でデータをフィルタリングしdeferred.reject(anotherReason)
、拒否の理由で呼び出すことができます。
Ryan Viceがコメントで示唆したように、いわば、応答を少しいじらない限り、これは有用とは見なされない可能性があります。
のでsuccess
とerror
1.4以降廃止され、多分通常の約束のメソッドを使用することをお勧めしますthen
とcatch
、それらのメソッド内のレスポンスを変換し、その変換された応答の約束を返します。
私は両方のアプローチと3番目の中間のアプローチで同じ例を示しています。
success
そしてerror
アプローチ(success
そしてerror
HTTP応答$q
のpromiseを返すため、データのpromiseを返すための助けが必要です):
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
テストでpromiseの動作を模擬するために使用する必要があります)。
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);