0

J'ai enregistré certaines clés d'URL de sujet dans localStorage et je veux maintenant les parcourir pour obtenir le contenu de chacune d'entre elles.Extension Chrome - URL XHR à partir d'un tableau

// Walk through saved subjects 
allSubjects = JSON.parse(localStorage.getItem('subjects')); 
var i = 0; 
var ii = 0; 

var xhrIn = []; 
for (i = 0; i < allSubjects.length; i++) { 
    xhrIn[i] = new XMLHttpRequest(); 
    xhrIn[i].open("GET", "https://myserver.com/" + allSubjects[i], true); 
     xhrIn[i].onreadystatechange = function() { 
      if (xhrIn[ii].readyState == 4) { 
       console.log(xhrIn[ii].responseText); 

       percents = Math.floor((((ii+1)/allSubjects.length)*100)); 
       $("div#status").text('Downloading... ' + percents + '%'); 

       // Final phase 
       if ((ii+1) == allSubjects.length) { 
        $("div#status").text("All downloaded and saved in console."); 
       } 
       ii++; 
      } 
     }; 
     xhrIn[i].send(); 
    } 
} 

Ce ne fonctionne pas, il ne saisit que la première URL, après que mon journal de la console indique que toutes les autres URL ont été contactés, mais xhrIn [i] .onreadystatechange fermeture n'a jamais été exécuté.

Cela semble un peu magique pour moi ... Quelqu'un peut-il m'expliquer ce comportement?

+1

La commande n'est pas garantie, ii ce qui se passe à l'intérieur est erroné. – epascarello

Répondre

0

Oui, je suis d'accord avec epascarello, il y a quelques problèmes fondamentaux avec ce code. Il n'y a pas de garantie que les rappels assignés à exécuter dans l'ordre que vous avez l'intention. Si vous voulez les faire fonctionner dans l'ordre, essayez quelque chose comme ceci:

var urls = ['test.php', 'test2.php', test3.php'];// and so on 

function myRequest(){ 
    if(urls.length > 0){ 
     var nextUrl = urls.pop(); //TAKE THE NEXT URL (pop() removed from the end) 
     var xhrIn = new XMLHttpRequest(); 
     xhrIn.open("GET", "https://myserver.com/" + nextUrl, true); 
     xhrIn.onreadystatechange = function() { 
      if (xhrIn.readyState == 4) { 
       console.log(xhrIn.responseText); 
       //THE FOLLOWING LINE WILL OBVIOUSLY NOT WORK ANY MORE 
       //percents = Math.floor((((ii+1)/urls.length)*100)); 
       //$("div#status").text('Downloading... ' + percents + '%'); 
       myRequest(); //RECUR WHEN DONE WITH PREVIOUS REQUEST 
      } 
     } 

    } 
} 
+0

Le comptage en pourcentage peut être effectué en transférant la variable i à chaque itération en tant qu'argument myRequest. ;-) –

0

ai pas testé, mais devrait être quelque chose comme ceci:

for (i = 0; i < allSubjects.length; i++) { 
    xhrIn[i] = new XMLHttpRequest(); 
    xhrIn[i].open("GET", "https://myserver.com/" + allSubjects[i], true); 

    xhrIn[i].onreadystatechange = (function(ii) { 
     return function() { 
      if (xhrIn[ii].readyState == 4) { 
       console.log(xhrIn[ii].responseText); 
      } 
     }; 
    })(i); 

    xhrIn[i].send(); 

} 

Votre calcul actuel pour cent sauteront sur la place que les fonctions de rappel pourraient être appelées dans un ordre aléatoire. Vous auriez probablement besoin de repenser cette partie (créer un compteur global).