2010-12-07 53 views
0

Espérons que je manque juste quelque chose et est simple ...jquery .each() alternative n'est pas correctement mise en boucle

J'ai une page qui boucle une liste de URL, fait l'Ajax appelle les (avec jquery), récupère les données du code HTML renvoyé et l'affiche dans une table. Ces appels fonctionnent bien. Depuis saisir ces données en temps réel prend un certain temps (peut-être jusqu'à 5 minutes pour parcourir la liste, retourner les données, afficher, etc.) les navigateurs comme Chrome et IE 'se verrouiller' pendant ce traitement lourd - Chrome effectivement affiche périodiquement le message «Page ne répond pas», alors que IE semble juste être suspendu, puis tout à coup, les résultats s'affichent à l'écran.

Pour résoudre ce problème, je l'ai étudié comment optimiser la fonction .each() jQuery et trouvé un plugin personnalisé appelé slowEach (LINK) qui insère essentiellement un petit délai d'attente après chaque itération de boucle - de sorte que le navigateur obtient un réponse, et ne pense pas que le client ne répond pas. J'ai mis à jour mon code pour appeler le plugin slowEach au lieu de .each et tout fonctionne bien, PRESQUE! Il semble que, après la première itération - le plugin exécute réellement du code supplémentaire - jusqu'à la fin de ma fonction de rappel, il veut soudainement revenir dans la boucle et continuer le reste des itérations correctement.

J'ai du mal à comprendre pourquoi cela se produit.

Voici mon code (parseXML est juste une fonction de rappel qui traite certaines données XML):

function parseXml(x) 
{ 
    var $rowArray = $(x).find("[nodeName=z:row]"); 

    $rowArray.slowEach(250, function(index) { 
    // ... processing each returned row 
    }); 
// ... extra processing after the loop is completed. Show data on the screen. 
}; 

Voici le plugin slowEach:

$.slowEach = function(array, interval, callback) { 
     if(! array.length) return; 
     var i = 0; 
     next(); 
     function next() { 
      if(callback.call(array[i], i, array[i]) !== false) 
       if(++i < array.length) 
        setTimeout(next, interval); 
     } 
    }; 

    $.fn.slowEach = function(interval, callback) { 
     $.slowEach(this, interval, callback); 
}; 

Ce code obtient en quelque sorte au « extra traitement 'partie de mon code - seulement sur la première itération à travers la boucle. Très étrange. Peut-être que certains globes oculaires supplémentaires peuvent m'aider à comprendre pourquoi le code le fait. Faites-moi savoir si plus d'informations sont nécessaires! Merci.

Répondre

1

Lorsque .slowEach utilise setTimout, il reporte essentiellement l'exécution de cette fonction (le contenu de la fonction each) jusqu'à ce que tous les autres traitements de page soient terminés. Par conséquent, le code en dehors des appels slowEach s'exécuteront tous, y compris le code après son appel. Ce que vous devez faire est d'ajouter une autre fonction à la fonction .sloweach à appeler après que tous les éléments ont été traités, et y mettre votre code // ... extra processing ....

code non testé, mais cela devrait fonctionner ou au moins obtenir que vous allez dans la bonne direction:

function parseXml(x) 
{ 
    var $rowArray = $(x).find("[nodeName=z:row]"); 

    $rowArray.slowEach(250, function(index) { 
     // ... processing each returned row 
    }, function() { 
     // ... extra processing after the loop is completed. 
     // Show data on the screen. 
    }); 
}; 

Modifier le plugin:

$.slowEach = function(array, interval, callback, onCompletion) { 
     if(! array.length) return; 
     var i = 0; 
     next(); 
     function next() { 
      if(callback.call(array[i], i, array[i]) !== false) 
       if(++i < array.length) 
        setTimeout(next, interval); 
       else 
        setTimeout(onCompletion, interval); 
     } 
    }; 

    $.fn.slowEach = function(interval, callback, onCompletion ) { 
     $.slowEach(this, interval, callback, onCompletion ); 
}; 
+0

Impressionnant! Cela a fonctionné PARFAIT! Code exécuté lors de la première exécution. Regarder dans setTimeout était définitivement le coupable. Je vais devoir en lire un peu plus. Merci jball. – tresstylez

+0

@tresstylez, heureux d'aider. Voici une bonne ressource sur le calendrier javascript: http://ejohn.org/blog/how-javascript-timers-work/ – jball