AngularJS - $ q.all()失败

dom*_*kun 17 ajax promise angularjs q

我正在尝试填充一些解决一系列远程调用的本地数据.
当每个承诺都得到解决后,我会加载数据并继续.

该方法$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)
        })
Run Code Online (Sandbox Code Playgroud)


问题是,这段代码没有弹性.
如果这些呼叫中的任何一个失败,没有人会得到鱼!

在try/catch语句中包装调用只会导致$q.all()完全忽略该条目,即使没有失败(请注意func中的console.log)...

        $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)
        })
Run Code Online (Sandbox Code Playgroud)

输出:

[宾语]


有关如何将其包裹起来以保持弹性的任何暗示?


感谢@dtabuenc,我更进了一步.实现错误回调,我可以避免链断开,并推送已解决的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)
        })
Run Code Online (Sandbox Code Playgroud)

被调用者代码(注入异常)

    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
                }
            })
    },
Run Code Online (Sandbox Code Playgroud)

Esa*_*ija 25

这将工作,但也将错误推送到数组.

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);
})
Run Code Online (Sandbox Code Playgroud)

你也应该提高对promises的理解,你永远不应该使用try-catchpromises - 当使用promises时,你使用.catch()方法(其他一切都是隐含的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);
})
Run Code Online (Sandbox Code Playgroud)