Vous ne faites pas synchrone ajax dans le navigateur (bien sur le plan technique, vous pouvez, dans certaines circonstances, mais il est vraiment une mauvaise idée de le faire, car il bloque le navigateur lors de l'appel ajax). Au lieu de cela, vous remodelez votre boucle de sorte qu'elle n'effectue que l'appel ajax suivant lorsque le précédent est terminé, ce qui signifie que vous devez effectuer une boucle manuellement, vous ne pouvez pas utiliser une boucle for
. Puisque votre code est pseudo-code (vous n'affichez pas l'opération réelle ajax), j'utiliserai un exemple jQuery ajax, mais vous pouvez remplacer n'importe quelle fonction ajax tant qu'elle renvoie une promesse ou utilise un rappel pour signaler quand c'est fait.
L'idée générale est que vous créez une fonction pour votre appel ajax et que vous utilisez le rappel de fin pour incrémenter votre index, puis exécuter l'itération suivante de votre boucle.
function runLoop(data) {
var i = 0;
function next() {
if (i < data.length) {
return $.ajax(data[i]).then(function(data) {
++i;
return next();
});
else {
// all done with loop
}
}
return next();
}
// call it like this
runLoop(someArray).then(function() {
// all done here
});
Si vous ne disposez pas d'un tableau de données, mais je veux juste un indice de boucle:
function runLoop(limitVar) {
var i = 0;
function next() {
if (i < limitVar) {
return $.ajax(something_with_i_in_it).then(function(data) {
++i;
return next();
});
else {
// all done with loop
}
}
return next();
}
// call it like this
runLoop(theLimit).then(function() {
// all done here
});
Si votre limitVar n'est pas grand et il n'y a pas d'autre logique qui pour décider de poursuivre ou non la boucle, vous pouvez également utiliser un peu plus simple modèle si vous avez une fonction ajax qui renvoie une promesse:
function runLoop(limitVar) {
var p = Promise.resolve();
for (var i = 0; i < limitVar; i++) {
p = p.then(function(prevResult) {
return someAjax(i);
});
}
return p;
}
// call it like this
runLoop(theLimit).then(function() {
// all done here
});
Si vous n'utilisez les fonctions ajax qui renvoient une promesse, il est seulement quelques lignes de code pour envelopper votre fonction avec celle qui le fait et vous pouvez ensuite utiliser plus facilement ces modèles de conception.
@KevinB Promise.all() on tire toutes les demandes à la fois. Si la taille d'un tableau est assez grande, cela va sûrement épuiser les ressources, ce qui entraînera des demandes défaillantes. – cepharum
Vous pouvez utiliser [] .reduce pour créer une chaîne qui les appelle l'une après l'autre. Voici par exemple: https://stackoverflow.com/questions/21372320/how-to-chain-execution-of-array-of-functions-when-every-function-returns-deferre –
Passer aux promesses signifie passer à asynchrone. – Bergi