prosource

$q.all()에서는 동작하는 콜과 실패하는 콜이 있을 경우 어떻게 됩니까?

probook 2023. 3. 29. 21:36
반응형

$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 콜이 동작하면 allResponse 배열이 데이터로 채워집니다.

어떤 함수가 실패하면 두 번째 함수가 호출되고 오류 변수가 세부 정보를 제공하는 것으로 알고 있습니다.

그러나 응답 중 일부는 작동하고 다른 일부는 실패하면 어떻게 되는지 누군가 설명해 줄 수 있습니까?

약속 도서관이 그 기반이기 때문에Q구현에서는 첫 번째 약속이 거부되는 즉시 거부 콜백이 호출되며 오류가 발생합니다.그것은 다른 약속들이 해결되기를 기다리지 않는다.의 메뉴얼을 참조해 주세요.Q https://github.com/kriskowal/q 를 참조해 주세요.Q. 이 모든 것은 다음과 같습니다.

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에서만 지원되지만 여전히 유용한 tidbit

장애 발생 시 즉시 거부하지 않고 모두 처리하려는 경우allSettled

의사는 다음과 같이 말합니다.

모든 약속이 이행되거나 거부될 때까지 기다리는 경우 allSettled를 사용할 수 있습니다.

Q.allSettled(promises)
.then(function (results) {
    results.forEach(function (result) {
        if (result.state === "fulfilled") {
            var value = result.value;
        } else {
            var reason = result.reason;
        }
    });
});

여기 그것에 대한 작은 답이 있다.이 바이올린으로 어떤 약속에서 오류가 발생했을 때 어떻게 작동하는지 알 수 있습니다.

$q.all([test1(), test2()]).then(function() {
  // success
}, function() {
  // error
});

http://jsfiddle.net/wd9w0ja4/

allSettled 기능을 angular로 $q에 추가하는 새로운 angular 패키지를 찾았습니다.

https://github.com/ohjames/angular-promise-extras

나의 경우 성공하든 실패하든 간에 마지막 약속이 언제 해결되었는지 알아야 했다.$q.all은 옵션이 아닙니다.하나가 실패하면 즉시 다운되기 때문입니다.모든 데이터가 다음 페이지에 로드될 수 있도록 처리(또는 처리되지 않음)되는 경우에만 사용자를 리디렉션할 수 있도록 하기 위해 필요했습니다.결국 이렇게 됐어요.

  1. 또한 구현된 각 약속/콜은 콜백에 실패합니다.콜백에서는 성공과 실패의 양쪽에서 "리다이렉트" 함수가 호출됩니다.
  2. 이 함수 카운터는 콜마다 증가하는 값으로 설정됩니다.이것이 약속/콜 수에 도달하면 다음 뷰로 리다이렉트 됩니다.

나는 그것이 꽤 재미없는 방법이라는 것을 알지만 그것은 나에게 효과가 있었다.

$q에 전달하기 전에 $http 약속의 오류 조건을 간단히 처리할 수 없을까요? 약속은 체인으로 연결되어 있으므로 다음과 같이 작동합니다.

return $http.put('/api/' + $scope.entityType + '/' + entityId, rowData).then(function(r){return r;}, angular.noop);

할 수 noop을 됩니다.$q.all실패로부터.

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

반응형