AngularJS - fail resilence on $q.all()

可紊 提交于 2019-11-29 01:24:12

This will work but also push the errors to the array.

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);
})

You should also improve your understanding of promises, you never should use try-catch with promises - when using promises, you use the .catch() method (with everything else being implicitly a try). This works for normal errors as well as asynchronous errors.


If you want to totally ignore the errors:

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);
})

I think it's easier to do :

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

I'm not sure what you mean by resilient. What do you want to happen if one of the promises fails?

Your try-catch won't work because the promise will fail asynchronously.

You can however pass in an error handler as the second parameter to the then() call and do whatever you wish there.

Same issue here. For those of you with for loops: inside a then response:

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's answer seems like a workaround to a problem. You can't resolve the problem outside the main contributor to the problem: $q.

It seems a bit wiser to have reject callbacks for each then (2nd argument) and in there to insert $q.reject(...).

Example:

$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
    }
)

This is particularly indicated when the UI model depends on all ajax calls.

Personally I think this is the safe way to proceed anyway, because most of the times you do want to push some server messages to some toast component on the reject callbacks, or alert the user in some way (queuing 7 ajax calls doesn't mean you can't show anything because 1 failed - it means you won't be able to show some region of the screen - that needs a specialized feedback to the user).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!