2014-10-29 18 views
5

Ich bin dabei, einige alte Code, der jQuery Deferred Objekte verwendet und ich schreibe mit Bluebird/ES6 Promises zu ersetzen.How to run nach allen Javascript ES6 Versprechen sind gelöst

Wenn ich mehrere asynchrone Aufrufe habe, wie kann ich eine Funktion auslösen, nachdem alle Versprechen gelöst sind.

Mit jQuery Deferreds wäre es so etwas wie dieses:

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

Wie umschreiben ich dies mit ES6 Versprechen Syntax?

+1

Mit jQuery Versprechen Syntax, die '.when.apply $ könnte dann (...' - viel ($, requests.map ($ erhalten).). cleaner –

Antwort

5

Da dies neben dem Sie bereits hier bekommen zwei guten Lösungen getaggt ist eine „drossel“ Art und Weise:

var requests = [...]; 

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

Dies ist wahrscheinlich so einfach wie es geht.

Wie die anderen darauf hingewiesen haben, wäre die native es6 Weise zu verwenden Promise.all, keine Promise.resolve oder explizite Erstellung erforderlich ist. Der sauberste Weg mit nativer Versprechen wäre wahrscheinlich:

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

}); 
+0

Große Antwort wirklich und ich schätze die Bluebird-Syntax. Ich verwende derzeit Bluebird, kann aber die native Syntax beibehalten, da ich Bluebird möglicherweise entfernen möchte, wenn ES6 offiziell in den wichtigsten Browsern unterstützt wird. – dave

5

Verwenden Promise.all. Beachten Sie, dass es ein iterable wie ein Array als sein Argument verwendet, im Gegensatz zu $.when, so dass die .apply nicht benötigt wird.

Sie möchten auch das jQuery Deferred in ein systemeigenes ES6-Versprechen konvertieren, indem Sie Promise.resolve(thejQueryDeferred) verwenden. EDIT: Dies geschieht implizit durch den Aufruf an Promise.all, so ist wirklich optional.

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

Danke, aktualisiert Beachten Sie, dass einfach 'Promise.resolve (thejQueryDeferred)' 'genug ist, um ein jQuery Deferred in ein ES6-Versprechen zu konvertieren (' Promise.resolve' prüft auf die 'then'-Eigenschaft und verhält sich entsprechend). – Shai

+0

@dfsq eigentlich - Es ist. Native Versprechungen wurden um die Promises/A + aufgebaut, die wiederum so aufgebaut sind, dass jQuery-Versprechungen konsumiert werden können. Dies ist beabsichtigt. –

+0

Was den '.resolve' Kommentar betrifft - müssen Sie eigentlich nicht Tun Sie dies, die 'Promise.resolve' wird automatisch für Sie erledigt, wenn eine native Versprechungen eine fremde' then'able konsumiert. Sie können dies sehen i n der Spezifikation (oder sogar MDN, mit der Sie verknüpft haben). –