How to run after all javascript ES6 Promises are r

2019-01-19 22:56发布

问题:

I'm in the process of replacing some old code that used jQuery Deferred objects and I am rewriting using Bluebird/ES6 Promises.

If I have multiple asynchronous calls, how can I trigger a function after all the promises are resolved.

Using jQuery Deferreds it would be something like this:

var requests = [...]; //some arbitrary data that is iterated to generate multiple ajax requests
var promises = [];
resuests.forEach(function(endpoint) {
    promises.push($.ajax({url: endpoint}));
});

$.when.apply($, promises).then(function() {
    alert('all promises complete!');
});

How do I rewrite this using ES6 Promise syntax?

回答1:

Since this is tagged bluebird in addition to the two good solutions you have already gotten here is a more "bluebird" way:

var requests = [...];

Promise.map(requests, $.get).then(function(results){
    alert('all promises complete!');
});

This is probably as simple as it gets.

As the others have pointed out, the native es6 way would be to use Promise.all, no Promise.resolve or explicit creation is needed. The cleanest way with native promises would probably be:

var requests = [...];
Promise.all(requests.map($.get)).then(function(results){

});


回答2:

Using Promise.all. Note that it takes an iterable such as an Array as its argument, unlike $.when, so doesn't need the .apply.

You'll also want to convert the jQuery Deferred to a native ES6 promise using Promise.resolve(thejQueryDeferred). EDIT: This gets done implicitly by the call to Promise.all, so is really optional.

Whole code:

var requests = [...]; //some arbitrary data that is iterated to generate multiple ajax requests
var promises = [];
requests.forEach(function(endpoint) {
    var nativePromise = Promise.resolve($.ajax({url: endpoint})); // if you want to make it clear that you're converting from jQuery Deferred to ES6 promise!
    promises.push(nativePromise);
});

Promise.all(promises).then(function() {
    alert('all promises complete!');
});