J'ai écrit cette fonction qui devrait l'exécuter pour la boucle, puis le rappel à la fin, mais elle continue d'exécuter le rappel avant de terminer la boucle. Les seules solutions que j'ai lues ont indiqué que l'utilisation d'un rappel résoudrait ce problème, mais cela ne semble pas faire beaucoup de différence.

function run(callback){
  for(var i = 0; i < urls.length; i++){
    request(url, function(error, resp, body){
      //uses cheerio to iterate through some elements on the page
      //then saves to an object for a future response  
    });
    callback();
  }
}
0
txnnxr 10 mars 2016 à 03:45

3 réponses

Meilleure réponse

J'ajouterais une variable appelée totaltasks et une autre appelée tasksfinished. Ensuite, lorsqu'une demande est terminée, incrémentez tasksfinished et appelez votre rappel chaque fois que tasksfinished est égal à totaltasks:

function run(callback){
  var totaltasks = urls.length;
  var tasksfinished = 0;

  // helper function
  var check = function() {
    if(totaltasks == tasksfinished) {
       callback();
    }
  }

  for(var i = 0; i < totaltasks; i++){
    try {
      request(url, function(error, resp, body) { 

        tasksfinished++;
        check();
     });
    } catch(e) {
      tasksfinished++;
      check();
    }
  }
};
1
Santiago Hernández 10 mars 2016 à 01:01

Tout d'abord, votre exemple de code manque de crochets. request est probablement une bibliothèque asynchrone. Donc, lors de son appel de fonction, il s'enregistre dans la boucle d'événements et revient immédiatement. Cela signifie que vous appelez le rappel immédiatement, probablement sans que la demande soit terminée. Le bouclage synchrone avec les fonctions asynchrones ne fonctionnera donc pas.

Utilisez quelque chose comme Promesses, Continuation Passing ou enregistrez une variable qui vérifie si tous les appels sont déjà retournés.

0
eljefedelrodeodeljefe 10 mars 2016 à 01:12

Vous devez déplacer votre fonction de rappel à l'intérieur du rappel de demande:

function run(callback){
  for(var i = 0; i < urls.length; i++){
     request(url, function(error, resp, body){    
        //uses cheerio to iterate through some elements on the page
        //then saves to an object for a future response  
         callback();
     });

}
0
Adam 10 mars 2016 à 00:54