Nie byłeś zbyt szczegółowy w swoim kodzie, więc wymyślę scenariusz. Powiedzmy, że masz 10 wywołań Ajax i chcesz zebrać wyniki z tych 10 wywołań AJAX, a gdy wszystkie się zakończą, chcesz coś zrobić. Możesz to zrobić w ten sposób, gromadząc dane w tablicy i śledząc, kiedy zakończy się ostatnia:
Licznik ręczny
var ajaxCallsRemaining = 10;
var returnedData = [];
for (var i = 0; i < 10; i++) {
doAjax(whatever, function(response) {
// success handler from the ajax call
// save response
returnedData.push(response);
// see if we're done with the last ajax call
--ajaxCallsRemaining;
if (ajaxCallsRemaining <= 0) {
// all data is here now
// look through the returnedData and do whatever processing
// you want on it right here
}
});
}
Uwaga: obsługa błędów jest tutaj ważna (nie jest wyświetlana, ponieważ jest specyficzna dla sposobu wykonywania połączeń Ajax). Będziesz chciał pomyśleć o tym, jak poradzisz sobie z przypadkiem, gdy jedno wywołanie ajax nigdy się nie kończy, albo z błędem, albo utknie na długi czas lub po długim czasie upłynie.
jQuery Promises
Dodając do mojej odpowiedzi w 2014 roku. Obecnie obietnice są często używane do rozwiązywania tego typu problemów, ponieważ jQuery $.ajax()
już zwraca obietnicę i $.when()
poinformuje Cię, kiedy grupa obietnic zostanie rozwiązana, i zbierze wyniki zwrotu:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push($.ajax(...));
}
$.when.apply($, promises).then(function() {
// returned data is in arguments[0][0], arguments[1][0], ... arguments[9][0]
// you can process it here
}, function() {
// error occurred
});
Standardowe obietnice ES6
Jak określono w odpowiedzi kba : jeśli masz środowisko z wbudowanymi natywnymi obietnicami (nowoczesna przeglądarka lub node.js lub używając babeljs transpile lub używając wypełnienia obietnicy), możesz użyć obietnic określonych w ES6. Zobacz tę tabelę, aby uzyskać informacje o obsłudze przeglądarek. Obietnice są obsługiwane w prawie wszystkich obecnych przeglądarkach, z wyjątkiem IE.
Jeśli doAjax()
zwróci obietnicę, możesz to zrobić:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
// returned data is in arguments[0], arguments[1], ... arguments[n]
// you can process it here
}, function(err) {
// error occurred
});
Jeśli chcesz wykonać operację asynchroniczną niezwiązaną z obietnicą w taką, która zwraca obietnicę, możesz ją „obiecać” w następujący sposób:
function doAjax(...) {
return new Promise(function(resolve, reject) {
someAsyncOperation(..., function(err, result) {
if (err) return reject(err);
resolve(result);
});
});
}
Następnie użyj powyższego wzoru:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
// returned data is in arguments[0], arguments[1], ... arguments[n]
// you can process it here
}, function(err) {
// error occurred
});
Bluebird obiecuje
Jeśli używasz bogatszej w funkcje biblioteki, takiej jak biblioteka obietnic Bluebird , ma ona wbudowane dodatkowe funkcje, które to ułatwiają:
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
// all ajax results here
}, function(err) {
// some error here
});