AngularJS에서 약속과 함께 성공 / 오류 / 최종 / 캐치를 사용
내가 사용하고 $http
AngularJS와에, 나는 반환 약속을 사용하는 방법과 핸들 오류를 모르겠어요.
이 코드가 있습니다 :
$http
.get(url)
.success(function(data) {
// Handle data
})
.error(function(data, status) {
// Handle HTTP error
})
.finally(function() {
// Execute logic independent of success/error
})
.catch(function(error) {
// Catch and handle exceptions from success/error/finally functions
});
이것이 좋은 방법입니까, 아니면 쉬운 방법입니까?
약속은 우리가 비동기 코드로 동기식으로 표현할 수 있도록하는 명령문에 대한 추상화입니다. 일회성 작업의 실행을 나타냅니다.
또한 일반 코드와 마찬가지로 예외 처리 기능을 제공하므로 약속에서 돌아 오거나 던질 수 있습니다.
동기 코드에서 원하는 것은 다음과 같습니다.
try{
try{
var res = $http.getSync("url");
res = someProcessingOf(res);
} catch (e) {
console.log("Got an error!",e);
throw e; // rethrow to not marked as handled
}
// do more stuff with res
} catch (e){
// handle errors in processing or in error.
}
약속 된 버전은 매우 비슷합니다.
$http.get("url").
then(someProcessingOf).
catch(function(e){
console.log("got an error in initial processing",e);
throw e; // rethrow to not marked as handled,
// in $q it's better to `return $q.reject(e)` here
}).then(function(res){
// do more stuff
}).catch(function(e){
// handle errors in processing or in error.
});
사용 잊어 success
및 error
방법에 관한 것이다.
두 방법 모두 각도 1.4에서 더 이상 사용되지 않습니다. 기본적으로 더 이상 사용되지 않는 이유는 체인 친화적 이지 않기 때문 입니다.
다음의 예를 통해, 나는에 대해 무엇을 의미하는지 설명하려고합니다 success
및 error
되지 인 체인 방식 친화적 인 . 주소가있는 사용자 객체를 반환하는 API를 호출한다고 가정 해 보겠습니다.
사용자 객체 :
{name: 'Igor', address: 'San Francisco'}
API를 호출하십시오.
$http.get('/user')
.success(function (user) {
return user.address; <---
}) | // you might expect that 'obj' is equal to the
.then(function (obj) { ------ // address of the user, but it is NOT
console.log(obj); // -> {name: 'Igor', address: 'San Francisco'}
});
};
어떻게 된 거예요?
때문에 success
및 error
반환 원래의 약속 , 즉에 의해 반환되는 한 $http.get
,의 콜백에 전달 된 개체가 then
전체 인 사용자 이전에 동일한 입력 말을하는 것입니다 객체, success
콜백.
우리가 2를 연결했다면 then
, 혼란이 덜했을 것입니다.
$http.get('/user')
.then(function (user) {
return user.address;
})
.then(function (obj) {
console.log(obj); // -> 'San Francisco'
});
};
이전 답변이 맞다고 생각하지만 여기에 또 다른 예가 있습니다 (Fayi, success () 및 error ()는 AngularJS 메인 페이지 에 따라 더 이상 사용되지 않습니다 :
$http
.get('http://someendpoint/maybe/returns/JSON')
.then(function(response) {
return response.data;
}).catch(function(e) {
console.log('Error: ', e);
throw e;
}).finally(function() {
console.log('This finally block');
});
어떤 유형의 세분성을 찾고 있습니까? 일반적으로 다음을 수행 할 수 있습니다.
$http.get(url).then(
//success function
function(results) {
//do something w/results.data
},
//error function
function(err) {
//handle error
}
);
여러 약속을 연결할 때 "최종"과 "캐치"가 더 나은 것으로 나타났습니다.
Angular $ http의 경우 success () 및 error () 함수는 응답 객체가 래핑되지 않으므로 콜백 서명은 $ http (...)와 같습니다 .success (function (data, status, headers, config))
then ()의 경우 아마도 원시 응답 객체를 처리 할 것입니다. AngularJS $ http API 문서에 게시 된 것과 같은
$http({
url: $scope.url,
method: $scope.method,
cache: $templateCache
})
.success(function(data, status) {
$scope.status = status;
$scope.data = data;
})
.error(function(data, status) {
$scope.data = data || 'Request failed';
$scope.status = status;
});
이전 약속 체인에서 새로운 오류가 발생하지 않으면 마지막 .catch (...)가 필요하지 않습니다.
I do it like Bradley Braithwaite suggests in his 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;
});
}])
Key Points:
The resolve function links to the .then function in our controller i.e. all is well, so we can keep our promise and resolve it.
The reject function links to the .catch function in our controller i.e. something went wrong, so we can’t keep our promise and need to reject it.
It is quite stable and safe and if you have other conditions to reject the promise you can always filter your data in the success function and call deferred.reject(anotherReason)
with the reason of the rejection.
As Ryan Vice suggested in the comments, this may not be seen as useful unless you fiddle a bit with the response, so to speak.
Because success
and error
are deprecated since 1.4 maybe it is better to use the regular promise methods then
and catch
and transform the response within those methods and return the promise of that transformed response.
I am showing the same example with both approaches and a third in-between approach:
success
and error
approach (success
and error
return a promise of an HTTP response, so we need the help of $q
to return a promise of data):
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
and catch
approach (this is a bit more difficult to test, because of the throw):
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;
}
There is a halfway solution though (this way you can avoid the throw
and anyway you'll probably need to use $q
to mock the promise behavior in your tests):
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;
}
Any kind of comments or corrections are welcome.
'Programming' 카테고리의 다른 글
풍부한 Word 문서를 만들 수있는 Java API가 있습니까? (0) | 2020.08.04 |
---|---|
Django에서 CSS를 어떻게 사용합니까? (0) | 2020.08.04 |
수정 방법 : android.app.RemoteServiceException : 패키지에서 게시 된 잘못된 알림 * : 아이콘을 작성할 수 없음 : StatusBarIcon (0) | 2020.08.03 |
템플릿 함수를 명시 적으로 인스턴스화하려면 어떻게해야합니까? (0) | 2020.08.03 |
Windows 용 git bash에서 드라이브 변경 (0) | 2020.08.03 |