2014-10-29 13 views
5

Sto sostituendo un vecchio codice che utilizza jQuery oggetti differiti e sto riscrivendo usando Bluebird/ES6 Promises.Come eseguire dopo aver risolto tutte le promesse di javascript ES6

Se ho più chiamate asincrone, come posso attivare una funzione dopo che tutte le promesse sono state risolte.

utilizzando jQuery Deferreds sarebbe qualcosa di simile:

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

Come faccio a riscrivere questo utilizzando la sintassi ES6 Promessa?

+1

Con sintassi promessa jQuery che potrebbe essere '$ .when.apply poi (...' - molto ($, requests.map ($ ottenere).). cleaner –

risposta

5

Dal momento che questo è etichettato in aggiunta ai due buone soluzioni che avete già ottenuto qui è un modo più "Bluebird":

var requests = [...]; 

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

Questo è probabilmente semplice come si arriva.

Come gli altri hanno sottolineato, il modo es6 nativo sarebbe quello di utilizzare Promise.all, non Promise.resolve o è necessaria la creazione esplicita. Il modo più pulito con promesse nativi probabilmente sarebbe:

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

}); 
+0

Ottima risposta davvero e apprezzo la sintassi Bluebird. Attualmente sto usando Bluebird, ma potrei attenermi alla sintassi nativa in quanto potrei considerare di rimuovere Bluebird quando ES6 è ufficialmente supportato nei principali browser. – dave

5

Utilizzo di Promise.all. Si noti che il numero accetta un valore come una matrice come argomento, diversamente da $.when, quindi non è necessario lo .apply.

Dovrai anche convertire jQuery Deferred in una promessa ES6 nativa usando Promise.resolve(thejQueryDeferred). EDIT: Questo viene eseguito implicitamente dalla chiamata a Promise.all, quindi è davvero facoltativo.

codice totale:

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!'); 
}); 
+0

Grazie, aggiornato. Nota che semplicemente 'Promise.resolve (thejQueryDeferred)' è sufficiente per convertire un jQuery Deferred in una Promessa ES6 ('Promise.resolve' controlla la proprietà' then' e agisce di conseguenza). – Shai

+0

@dfsq - Le promesse native sono state costruite attorno a Promises/A +, che a sua volta è costruito in modo tale da consumare le promesse di jQuery è possibile Questo è inteso –

+0

Per quanto riguarda il commento '.resolve' - in realtà non è necessario fai questo, il 'Promise.resolve' viene fatto automaticamente per te quando un nativo promette di consumare un' estraneo 'allora. Puoi vederlo n la specifica (o anche MDN, a cui ti sei collegato). –