当前位置: 动力学知识库 > 问答 > 编程问答 >

javascript - How to '$.all' a dynamic set of promises?

问题描述:

Let's say we have 3 promises and we pass them to $q.all. This will return a new promise that's resolved when the 3 promises are resolved.

Now if before the 3 promises are resolved I actually decide I want a 4th promise to be resolved as well, can this be done?

I tried something like:

var promises = [promise1, promise2, promise3];

var allDone = $q.all(promises);

promises.push(promise4);

In the above, allDone is resolved as soon as first 3 promises are resolved, but I would like it to wait for the 4th promise as well.

Or am I missing the point of promises here? Maybe I shouldn't be using promises for such cases?

Update: As answered, $q.all isn't capable of doing what I want. My question: Is there another way to know when a dynamic set of promises are resolved, so even when this set changes?

网友答案:

You can't add promises to the array after the fact and expect it to influence the previous .all(). That's not how .all() works. You can, instead do this:

var promises = [promise1, promise2, promise3];
var allDone = $q.all(promises);

$q.all([allDone, promise4]).then(function() {
    // all four promises are done here
}); 

Or, you could just abandone the allDone promise and remake a new .all() like this:

var promises = [promise1, promise2, promise3];
var allDone = $q.all(promises);

promises.push(promise4);
var all4Done = $q.all(promises);

Based on your comments, here's another possibility. Let's say the eventual done handler you want called is in a function named allDoneNow(). Then, you could do something like this:

var promises = [promise1, promise2, promise3];
var allDone = $q.all(promises);
allDone.then(function(results) {
    // if no new promises have been added to the array
    if (promises.length === results.length) {
        // call our final handler
        return allDoneNow(results);
    } else {
        // wait for any new promises
        return $q.all(promises).then(allDoneNow);
    }
});

promises.push(promise4);

Or, if you want it recursive so it keeps checking for more, you can put it in a function like this that can be used recursively:

function waitAll(promiseArray) {
    return $q.all(promiseArray).then(function(results) {
        if (promiseArray.length <= results.length) {
            // everything currently in the promiseArray is now done
            return results;
        } else {
            // there are some new things in the promiseArray so
            // wait until they are done
            return waitAll(promiseArray);
        }
    });
}


var promises = [promise1, promise2, promise3];
waitAll(promises).then(function(results) {
    // all promises currently in the promises array are done
});

promises.push(promise4);
网友答案:

If you can check the source code of $q all() function, you will see that it just travels all promises with forEach() and return another promise which will resolve all result later on.

So if you push another promise into the array it does not effect it at all, as it already sets all promises and done with your promises array.

分享给朋友:
您可能感兴趣的文章:
随机阅读: