IT TIP

일부 호출이 작동하고 다른 호출이 실패하면 $ q.all ()은 어떻게됩니까?

itqueen 2020. 11. 24. 20:42
반응형

일부 호출이 작동하고 다른 호출이 실패하면 $ 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
});

http://jsfiddle.net/wd9w0ja4/


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:

  1. Each promise/call implemented also fail callback where "redirect" function is called in both success and fail callbacks.
  2. 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.

참고URL : https://stackoverflow.com/questions/19944922/what-happens-with-q-all-when-some-calls-work-and-others-fail

반응형