0

私は次のコードを持っています:

eventResourcesCall = $http.jsonp('https://apicall/to/serverA');
eventsDetailsCall = $http.get('https://apicall/to/serverB');

$q.all([eventResourcesCall, eventsDetailsCall]).then(function(values){
    //process data manipulation and merging
});

問題は、serverA と ServerB が使用できない場合があり、そのうちの 1 つが使用できない場合、データ処理コードが停止し、次のようなエラーが発生することです。

GET https://apicall/to/serverA?jsonp=angular.callbacks._0 404 (Not Found)

$http によって要求され、$q.all() によって実行された使用できない URL を適切に処理する方法について、ドキュメントを参照したり、回答を説明したりできますか?

私ができるようにしたいのは、URL にアクセスできないことを示してから、データ処理コードの中止を回避することです。

ありがとう!

4

2 に答える 2

2

私は間接的な約束を使用します:

var d1 = $q.defer(), d2 = $q.defer();

function NetworkError(reason) { this.reason = reason; }

eventResourcesCall = $http.jsonp('https://apicall/to/serverA').then(
    function(response) {
        d1.resolve(response);
    },
    function(err) {
        d1.resolve(new NetworkError(err));
    }
);
eventsDetailsCall = $http.get('https://apicall/to/serverB').then(
    function(response) {
        d2.resolve(response);
    },
    function(err) {
        d2.resolve(new NetworkError(err));
    }
);

$q.all([d1, d2]).then(function(values){
    var eventResources = values[0], eventsDetails = values[1];

    if( eventResources instanceof NetworkError ) {
        // handle error
    }
    else {
        // eventResources is good, use it
    }

    // and so on...
});

したがって、間接的な約束は常に解決され、all()成功します。ただし、解決値はNetworkError、このリクエストの実際のエラーを通知する特別なクラスである可能性があります。


これは間違いなくかさばりますが、いくつかのユーティリティメソッドで改善できます。

function makeIndirectPromise(httpPromise) {
    var ret = $q.defer();
    httpPromise.then(
        function(response) {
            ret.resolve(response);
        },
        function(err) {
            ret.resolve(new NetworkError(err));
        }
    );
    return ret.promise;
}

上記のコードは次のように変更されます。

function NetworkError(reason) { this.reason = reason; }

function makeIndirectPromise(httpPromise) { /* see above */ }

eventResourcesCall = makeIndirectPromise($http.jsonp('https://apicall/to/serverA'));
eventsDetailsCall = makeIndirectPromise($http.get('https://apicall/to/serverB'));

$q.all([eventResourcesCall, eventsDetailsCall]).then(function(values){
    var eventResources = values[0], eventsDetails = values[1];

    if( eventResources instanceof NetworkError ) {
        // handle error
    }
    else {
        // eventResources is good, use it
    }

    // and so on...
});
于 2013-10-10T08:14:11.690 に答える
1

Angular doc から$qへ: $http は promise を返すため、次のいずれかを使用して promise の拒否をキャッチできます。

$q.all([eventResourcesCall, eventsDetailsCall]).then(function(values){
    //process data manipulation and merging on Success
}).catch(function(errors){
    //Deal with your $http errors
}).finally(function(data){

});

また

$q.all([eventResourcesCall, eventsDetailsCall]).then(function(values){
    //process data manipulation and merging on Success
}, function(errors){
    //Deal with your $http errors
});
于 2013-10-10T08:15:04.817 に答える