programing

AngularJS - $q.all()에서 오류 복원력

muds 2023. 9. 28. 08:50
반응형

AngularJS - $q.all()에서 오류 복원력

일련의 원격 전화를 해결하기 위해 로컬 데이터를 채우려고 합니다.
모든 약속이 해결되면 데이터를 로드하고 진행합니다.

메소드$q.all( [] )는 정확히 다음을 수행합니다.

        $q.all([
            this.getUserInfo(11)
                .then(function (r) {
                    results.push(r)
                }),

            this.getUserConns()
                .then(function (r) {
                    results.push(r)
                }),

            this.getUserCtxs()
                .then(function (r) {
                    results.push(r)
                })
        ])
        .then(function () {
            console.log(results)
        })


문제는 이 코드가 복원력이 없다는 것입니다.
이 전화들 중 하나라도 실패하면, 아무도 물고기를 얻지 못합니다!

통화 내용을 시도/포착 문으로 포장하는 것은 단순히 다음과 같은 원인을 갖습니다.$q.all()실패하지 않더라도 항목을 완전히 무시합니다(console.log in func).

        $q.all([
            this.getUserInfo2(11)
                .then(function (r) {
                    results.push(r)
                }),

            function () {
                try {
                    this.getUserGroups()
                        .then(function (r) {
                            console.log(r)
                            results.push(r)
                        })
                }
                catch (err) {
                    console.log(err)
                }
            },
        ])
        .then(function () {
            console.log(results)
        })

출력:

[객체]


어떻게 하면 이걸 탄력있게 포장할 수 있을까요?


Thanks to @dtabuenc, I've gone one step further. Implementing the error callback, I can avoid the breaking of the chain, and push the values of the resolved promises.

하지만 콘솔에는 여전히 심술궂은 예외가 표시됩니다...비동기 요청을 시도/캐치할 수 없는 경우 어떻게 이를 제거할 수 있습니까?

발신자코드

    return $q.all([

            this.getUserInfo(user_id)
                .then(function (r) {
                    results['personal_details'] = r
                }),

            this.getUserConns()
                .then(
                    function (r) {
                    results['connections'] = r
                    },
                    function(err) {
                        console.log(err)
                    })

        ])
        .then(function () {
            return (results)
        })

호출 코드(예외와 함께 주입)

    getUserConns: function() {

        return __doCall( ws.getUserConnections, {} )
            .then( function(r) {

                // very generic exception injected
                throw new Error

                if (r && r.data['return_code'] === 0) {
                    return r.data['entries']
                }
                else {
                    console.log('unable to retrieve the activity - err: '+r.data['return_code'])
                    return null
                }
            })
    },

이렇게 하면 오류가 발생할 뿐만 아니라 배열에 오류가 발생하기도 합니다.

function push(r) {
    results.push(r);
}

$q.all([
    this.getUserInfo(11).then(push).catch(push),
    this.getUserConns().then(push).catch(push),
    this.getUserCtxs().then(push).catch(push)
])
.then(function () {
    console.log(results);
})

당신은 또한 약속에 대한 당신의 이해를 향상시켜야 합니다, 당신은 절대로 사용해서는 안됩니다.try-catch약속과 함께 - 약속을 사용할 때 당신은.catch()method (다른 모든 것은 암시적으로 a.try이는 비동기 오류뿐만 아니라 일반 오류에도 적용됩니다.


오류를 완전히 무시하려면 다음을(를)

function push(r) {
    results.push(r);
}

function noop() {}

$q.all([
    this.getUserInfo(11).then(push).catch(noop),
    this.getUserConns().then(push).catch(noop),
    this.getUserCtxs().then(push).catch(noop)
])
.then(function () {
    console.log(results);
})

제 생각에는 다음과 같은 작업을 하는 것이 더 쉬운 것 같습니다.

$q.all([
 mypromise1.$promise.catch(angular.noop),
 mypromise2.$promise.catch(angular.noop),
 mypromise1.$promise.catch(angular.noop)
])
.then(function success(data) {
 //.....
});

회복력이란 무엇을 의미하는지 잘 모르겠습니다.만약 그 약속들 중 하나가 실패한다면 당신은 어떻게 되기를 원합니까?

약속이 비동기적으로 실패하기 때문에 트라이캐치가 작동하지 않습니다.

그러나 오류 처리기를 에 두 번째 매개 변수로 전달할 수 있습니다.then()전화해서 거기서 하고 싶은 거 다 해요.

같은 문제입니다.루프를 사용하는 경우: 내부 응답:

var tracks = [];
var trackDfds = [];
for(var i = 0; i < res.items.length; i++){
    var fn = function () {
        var promise = API.tracks(userId, res.items[i].id);
        return promise.then(function (res) {
            if (res.items.length) {
              tracks.push(res.items);
            }
        }).catch(angular.noop);
    };
    trackDfds.push(fn());
}
$q.all(trackDfds)
    .then(function (res) {
        console.log(tracks);
    });

@Esailija의 대답은 문제를 해결하는 것처럼 보입니다.문제의 주요 원인이 되는 외부에서는 문제를 해결할 수 없습니다.$q.

각각의 콜백을 거절하는 것이 더 현명해 보입니다.then(두 번째 주장) 그리고 거기에 삽입할.$q.reject(...).

예:

$q.all([
    this.getUserInfo(11).then(
        function (response) { // UI data preparation for this part of the screen }, 
        function (response) {
           $q.reject(response);
        }
    ),
    // ...
])
.then(
    function () {
      // all good
    },
    function () {
      // at least one failed
    }
)

이것은 특히 UI 모델이 모든 ajax 호출에 의존하는 경우에 나타납니다.

개인적으로 저는 이것이 어쨌든 진행할 수 있는 안전한 방법이라고 생각합니다. 왜냐하면 대부분의 경우 서버 메시지를 거부 콜백의 토스트 구성 요소에 푸시하고 싶어하기 때문입니다.또는 어떤 방식으로든 사용자에게 알립니다(queuing 7 ajax calls는 1번 실패했기 때문에 아무것도 보여줄 수 없음을 의미하지 않습니다. 즉, 사용자에게 전문적인 피드백이 필요한 화면의 일부 영역을 보여줄 수 없음을 의미합니다.).

언급URL : https://stackoverflow.com/questions/20563042/angularjs-fail-resilence-on-q-all

반응형