Envoyer une requête AJAX à la fois à partir d'une boucle

je sais que cette question a été posée d'innombrables fois, mais je ne peux pas comprendre pour ma vie comment faire fonctionner cette réponse dans mon cas: attendre le retour de la fonction javascript async

je suis en boucle à travers quelques "chaînes de télévision" dans la boucle extérieure et puis en boucle à travers les dates de la semaine dans la boucle intérieure. Dans la boucle intérieure, je fais une requête ajax à un serveur pour récupérer les données et je les stocke/cache pour une utilisation ultérieure comme so

var dates = []; //<-- Contains a list of dates for the coming week 
var baseUrl = "http://www.someserver.com";
var storedChannels = [1,2,3,4,5,6,7,8,9,10,45,23,56,34,23,67,23,567,234,67,345,465,67,34];

for(ch = 0; ch < storedChannels.length; ch++) {   
    var channel = storedChannels[ch];
    for(d=0; d < 7; d++) {
        var currentDate = dates[d];
        ajax({    
            url: baseUrl+"?ch="+channel+"&dt=currentDate"+,
            complete: function(res) {
                CMLocalStore.setString('ch' + ch + "_" + scheduleDay, res);
            },
        });
        //Want to wait here till the ajax request completes.
        //Do not want to continue to next iteration.
        //Do not want to fire of 50 bazillion ajax requests all at once
        //Why? Very limited bandwidth scenario, plenty of channels  
    }
}

PS: NO JQuery s'il vous plaît! Plaine JS solutions d'

merci Beaucoup!

10
demandé sur Community 2011-02-21 15:35:58

5 réponses

Vous voulez quelque chose de ce genre. Je n'ai pas testé, mais j'espère que vous devriez obtenir l'idée.

var dates = []; //<-- Contains a list of dates for the coming week 
var baseUrl = "http://www.someserver.com";
var storedChannels = [1,2,3,4,5,6,7,8,9,10,45,23,56,34,23,67,23,567,234,67,345,465,67,34];

function ProcessNext(ch, d) {
    if (d < 7) {
        d++;
    } else {
        d=0;
        if (ch < storedChannels.length) {
            ch++;
        } else {
            return;
        }
    }

    var channel = storedChannels[ch];
    var currentDate = dates[d];
    ajax({    
        url: baseUrl+"?ch="+channel+"&dt=currentDate"+,
        complete: function(res) {
            CMLocalStore.setString('ch' + ch + "_" + scheduleDay, res);
            ProcessNext(ch, d);
            },
    });
}

ProcessNext(0, 0);
18
répondu andynormancx 2011-02-21 12:45:30

vous devez transformer votre boucle en une chaîne de callbacks.

au lieu d'utiliser une boucle, vous devriez faire votre callback appeler votre fonction d'origine, mais avec une valeur de paramètre plus élevée.

4
répondu SLaks 2011-02-21 12:40:30

Ce que vous essayez de faire est expliqué dans le Modèles D'Itération Asynchrone tutorial de Pedro Teixeira. Les exemples utilisent le noeud.js mais vous pouvez utiliser les mêmes modèles dans le navigateur. Fondamentalement, ce que vous devez faire est de convertir vos boucles en callbacks série en attente l'un de l'autre pour terminer, de sorte que la prochaine requête AJAX est lancée à partir du succès callback de la précédente etc Il peut être fait sans bloquer le navigateur, mais pas dans les boucles. Voir le tutoriel.

1
répondu rsp 2011-02-21 12:55:07

essentiellement, la réponse réside dans l'utilisation d'appels récursifs au lieu d'utiliser des boucles. Je voulais juste ajouter cette réponse pour n'importe qui qui pourrait être intéressé par "pour les nichages en boucle" plus profond que 2 niveaux. Comme vous pouvez le voir, il est facile à étendre à autant de "nichages" que vous le souhaitez. Le crédit Original va à VatooVatoo implémentation en Java sur les forums DaniWeb.

hérite le code, testé et fonctionne (sans les bits ajax bien sûr, mais vous pouvez l'ajouter vous-même):

<html>
<head>
<script type="text/javascript">
    function loopRecurse(a, b, c)
    {
        if(c >= 2) {
            b++;
            c=0;
            loopRecurse(a, b, c);
            return;
        }
        if(b >= 2) {
            a++;
            b=0;
            loopRecurse(a, b, c);
            return;
        }
        if(a >= 2) return;
        document.write("<div>" + a + "|" + b + "|" + c + "</div>");
        c++;
        loopRecurse(a, b, c);
    }
    loopRecurse(0, 0, 0);
</script>
</head>
<body>
    <!-- output
        0|0|0
        0|0|1
        0|1|0
        0|1|1
        1|0|0
        1|0|1
        1|1|0
        1|1|1
     -->
</body>
</html>
1
répondu n4rzul 2011-02-23 13:40:33

voir le XMLHttpRequest documentation (lié au MDC, mais cela ne devrait pas avoir d'importance). Fondamentalement la condition que vous cherchez est request.readyState==4 - présumant que vous avez votre ajax() retourner leXMLHttpRequest objet.

-2
répondu Shadikka 2011-02-21 12:41:07