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 有时可能不可用,当其中一个不可用时,数据处理代码停止,我收到类似于以下描述的错误:

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 回答