使用拒绝时可能无法处理拒绝并使用$ q捕获

时间:2017-03-28 16:55:29

标签: angularjs ecmascript-6

我有这样的JSON-RPC提供程序(用babel和webpack编译):

export default function() {
    var id = 1;
    function request(method, params) {
        return JSON.stringify({
            id: id++,
            method: method,
            params: params || []
        });
    }
    var uri;
    this.setup = function(user_uri) {
        uri = user_uri;
    };
    this.$get = ['$http', '$q', function($http, $q) {
        function rpc(method, params) {
            return $http({
                method: 'POST',
                url: uri,
                data: request(method, params)
            }).then(response => response.data);
        }
        var defer = $q.defer();
        rpc('system.describe').then(data => {
            var service = {};
            data.result.procs.forEach(spec => {
                service[spec.name] = function(...args) {
                    var defer = $q.defer();
                    if (args.length == spec.params.length) {
                        return rpc(spec.name, args).then(data => {
                            if (data.error) {
                                defer.reject(data.error);
                            } else {
                                defer.resolve(data.result);
                            }
                        });
                    } else {
                        defer.reject('Invalid arity expected ' +
                                     spec.params.length +
                                     ' got ' +
                                     args.length);
                    }
                    return defer.promise;
                };
            });
            defer.resolve(service);
        });
        return defer.promise;
    }];
};

我调用了一个函数:

        service.login('user', 'password').then(function(token) {
            if (token) {
                localStorage.setItem('notes_token', token);
                localStorage.setItem('notes_username', 'user');
            }
            console.log('token: ' + token);
        }).catch(function(error) {
            console.log(error);
        });

请求返回错误,我在控制台中得到了这个:

  

令牌:未定义   [错误]可能未处理的拒绝:用户未激活

为什么我从catch获取console.log并执行then

我也尝试过:

        service.login('user', 'password').then(function(token) {
            if (token) {
                localStorage.setItem('notes_token', token);
                localStorage.setItem('notes_username', 'user');
            }
            console.log('token: ' + token);
        }, function(error) {
            console.log(error);
        });

并获得相同的结果。我使用的是角1.6.3。

1 个答案:

答案 0 :(得分:0)

避免使用deferred antipattern!尽量不要使用$q.defer()。当您的rpc()函数拒绝其结果承诺时,您只是忽略它 - unhandled rejection

您需要使用

this.$get = ['$http', '$q', function($http, $q) {
    function rpc(method, params) {
        return $http({
            method: 'POST',
            url: uri,
            data: request(method, params)
        }).then(response => response.data);
    }
    return rpc('system.describe').then(data => {
//  ^^^^^^
        var service = {};
        for (const spec of data.result.procs) {
            service[spec.name] = function(...args) {
                if (args.length == spec.params.length) {
                    return rpc(spec.name, args).then(data => {
                        if (data.error) {
                            throw data.error;
//                          ^^^^^
                        } else {
                            return data.result;
//                          ^^^^^^
                        }
                    });
                } else {
                    return $q.reject('Invalid arity expected ' +
//                  ^^^^^^^^^^^^^^^^
                                 spec.params.length +
                                 ' got ' +
                                 args.length);
                }
            };
        }
        return service;
//      ^^^^^^
    });
}];