일부 호출이 작동하고 다른 호출이 실패하면 $ q.all ()은 어떻게됩니까?
일부 호출이 작동하고 다른 호출이 실패하면 $ q.all ()은 어떻게됩니까?
다음 코드가 있습니다.
var entityIdColumn = $scope.entityType.toLowerCase() + 'Id';
var requests = $scope.grid.data
.filter(function (rowData, i) {
return !angular.equals(rowData, $scope.grid.backup[i]);
})
.map(function (rowData, i) {
var entityId = rowData[entityIdColumn];
return $http.put('/api/' + $scope.entityType + '/' + entityId, rowData);
});
$q.all(requests).then(function (allResponses) {
//if all the requests succeeded, this will be called, and $q.all will get an
//array of all their responses.
console.log(allResponses[0].data);
}, function (error) {
//This will be called if $q.all finds any of the requests erroring.
var abc = error;
var def = 99;
});
모든 $ http 호출이 작동하면 allResponses 배열이 데이터로 채워집니다.
하나가 실패하면 두 번째 함수가 호출되고 오류 변수가 세부 정보를 제공한다는 것을 이해하고 있습니다.
그러나 누군가가 응답 중 일부가 작동하고 다른 응답이 실패하면 어떻게되는지 설명해 줄 수 있습니까?
Promise 라이브러리는 Q
구현을 기반으로 하기 때문에 첫 번째 Promise가 거부 되 자마자 Reject 콜백이 오류와 함께 호출됩니다. 다른 약속이 해결되기를 기다리지 않습니다. Q
https://github.com/kriskowal/q 문서를 참조하십시오 . Q.all에 대해 언급 된 내용입니다.
all 함수는 값 배열에 대한 약속을 반환합니다. 이 약속이 이행되면 배열에는 약속과 동일한 순서로 원래 약속의 이행 값이 포함됩니다. 주어진 약속 중 하나가 거부되면 반환 된 약속이 즉시 거부되고 나머지 배치를 기다리지 않습니다.
이 질문이 게시 된 지 오래되었지만 내 답변이 여전히 누군가에게 도움이 될 수 있습니다. 나는 단순히 모든 약속을 해결함으로써 비슷한 문제를 해결했지만, 반품을 통해 나중에 처리하여 오류가 있는지 확인할 수있었습니다. 다음은 일부 이미지 자산을 미리로드하는 데 사용되는 예제입니다.
var loadImg = function(imageSrc) {
var deferred = $q.defer();
var img = new Image();
img.onload = function() {
deferred.resolve({
success: true,
imgUrl: imageSrc
});
};
img.onerror = img.onabort = function() {
deferred.resolve({
success: false,
imgUrl: imageSrc
});
};
img.src = imageSrc;
return deferred.promise;
}
나중에 어떤 것이 오류인지 알 수 있습니다.
var promiseList = [];
for (var i = 0; i < myImageList.length; i++) {
promiseList[i] = loadImg(myImageList[i]);
}
$q.all(promiseList).then(
function(results) {
for (var i = 0; i < results.length; i++) {
if (!results[i].success) {
// these are errors
}
}
}
);
편집 : Kris Kowal의 Q에서만 지원되지만 여전히 유용한 정보
실패시 즉시 거부하지 않고 모두 처리하고 싶다면 사용 allSettled
Here's what the docs say:
If you want to wait for all of the promises to either be fulfilled or rejected, you can use allSettled.
Q.allSettled(promises)
.then(function (results) {
results.forEach(function (result) {
if (result.state === "fulfilled") {
var value = result.value;
} else {
var reason = result.reason;
}
});
});
Here is a small answer to it. In this fiddle you can see how it works, if an error occurs in some promise.
$q.all([test1(), test2()]).then(function() {
// success
}, function() {
// error
});
I've found a new angular package which add the allSettled functionality to $q in angular:
https://github.com/ohjames/angular-promise-extras
Could you not simply handle the error condition on your $http promises before passing them to $q? Promises are chained, so this should work:
return $http.put('/api/' + $scope.entityType + '/' + entityId, rowData).then(function(r){return r;}, angular.noop);
Obviously you could change the noop into any transformation you want but this prevents the rejection which prevents $q.all
from failing.
In my case I needed to know when last promise has been resolved no matter if successful or fail. $q.all was not an option because if one fails it goes down immediately. I needed this to make sure user will be redirected no matter what but only if all data are processed (or not) so they can be loaded on next page. So I ended up with this:
- Each promise/call implemented also fail callback where "redirect" function is called in both success and fail callbacks.
- In this function counter is set, which is increased with each call. If this reaches the number of promises/calls, redirect to next view is made.
I know it's quite a lame way to do it but it worked for me.
'IT TIP' 카테고리의 다른 글
dragenter 및 dragover 이벤트에서 드래그되는 항목 확인 (0) | 2020.11.24 |
---|---|
복잡한 플롯에 대한 수동 범례 구성 (0) | 2020.11.24 |
Tomcat과 TomEE, TomEE 및 TomEE Plus의 차이점은 무엇입니까? (0) | 2020.11.24 |
Angular2 : 자식 구성 요소 액세스 부모 클래스 변수 / 함수 (0) | 2020.11.24 |
사용자 인터페이스없이 Web API의 토큰 기반 인증 (0) | 2020.11.24 |