AngularJS: $q wait for all even when 1 rejected

后端 未结 8 1579
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-01 16:23

I\'ve been trying to wait for a couple of promises with Angular\'s $q but there seems to be no option to \'wait for all even when a promis is rejected\'. I\'ve created an exampl

相关标签:
8条回答
  • 2021-02-01 17:14

    A simple solution would be to use catch() to handle any errors and stop rejections from propagating. You could do this by either not returning a value from catch() or by resolving using the error response and then handling errors in all(). This way $q.all() will always be executed. I've updated the fiddle with a very simple example: http://jsfiddle.net/pHEf9/125/

    ...
    function handleError(response) {
        console.log('Handle error');
    }
    
    // Create 5 promises
    var promises = [];
    var names = [];
    for (var i = 1; i <= 5; i++) {
        var willSucceed = true;
        if (i == 2) willSucceed = false;
        promises.push(
          createPromise('Promise' + i, i, willSucceed).catch(handleError));
    }
    ...
    

    Be aware that if you don't return a value from within catch(), the array of resolved promises passed to all() will contain undefined for those errored elements.

    0 讨论(0)
  • 2021-02-01 17:17

    Analogous to how all() returns an array/hash of the resolved values, the allSettled() function from Kris Kowal's Q returns a collection of objects that look either like:

    { state: 'fulfilled', value: <resolved value> }
    

    or:

    { state: 'rejected', reason: <rejection error> }
    

    As this behavior is rather handy, I've ported the function to Angular.js's $q:

    angular.module('your-module').config(['$provide', function ($provide) {
        $provide.decorator('$q', ['$delegate', function ($delegate) {
            var $q = $delegate;
    
            $q.allSettled = $q.allSettled || function allSettled(promises) {
                // Implementation of allSettled function from Kris Kowal's Q:
                // https://github.com/kriskowal/q/wiki/API-Reference#promiseallsettled
    
                var wrapped = angular.isArray(promises) ? [] : {};
    
                angular.forEach(promises, function(promise, key) {
                    if (!wrapped.hasOwnProperty(key)) {
                        wrapped[key] = wrap(promise);
                    }
                });
    
                return $q.all(wrapped);
    
                function wrap(promise) {
                    return $q.when(promise)
                        .then(function (value) {
                            return { state: 'fulfilled', value: value };
                        }, function (reason) {
                            return { state: 'rejected', reason: reason };
                        });
                }
            };
    
            return $q;
        }]);
    }]);
    

    Credit goes to:

    • Zenuka for the decorator code
    • Benjamin Gruenbaum for pointing me in the right direction
    • The all implementation from Angular.js source
    0 讨论(0)
提交回复
热议问题