2009-10-13 7 views
1

J'utilise jQuery pour charger une table massive en lots de lignes. Je charge les lignes initiales, puis je fais des appels $ .ajax pour ajouter des lignes au corps de la table. À la fin de l'insertion du prochain bloc de lignes, j'appelle la méthode pour traiter le prochain bloc de lignes. Voir le code ci-dessous. Le problème est, même après tout le contenu est chargé, le javascript prétend encore être en cours d'exécution - quand je vais naviguer vers une autre page se plaint qu'il ya une routine javascript ralentir la page et que je veux l'avorter. À ce stade, il ne devrait pas fonctionner! Cette routine est initialement appelée à partir de la routine $ (function() {...}) (en attente). Des idées sur comment je suis censé empêcher cela de continuer après que tout a fini son travail?Javascript (jQuery) encore en cours d'exécution après tout ce que son travail est terminé

 function processNextChunk(c, t, s, p, x) { 
     var args = "{company_ID:" + c + ",shareholdingType:" + t + ",startIndex:" + s + ",pageSize:" + p + ",stack:'" + x + "'}"; 
     //alert(args); 
     $.ajax({ 
      type: "POST", 
      url: "TestStructure6.aspx/GetNextHierarchyPage", 
      data: args, 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      success: function(msg) { 
       //Append the content to the bottom of the table tag. 
       //Returning 2 arguments from the result, hence the split (initial 
       //value is an int, so not a big deal using pipe as a delimiter) 
       if (msg.d.length > 0) { 
        var slash = msg.d.indexOf('|'); 
        var r; 
        if (slash > 0) { 
         x = msg.d.substr(0, slash); 
         r = msg.d.substr(slash + 1, msg.d.length - slash); 
         $('#h > tbody').append(r); 
         if (r.length > 0) { 
          var percent = (s + p)/totalRows * 100; 
          $('#counter').html(parseInt(percent) + '%'); 
          setTimeout('processNextChunk(' + c + ', ' + t + ', ' + (s + p) + ', ' + p + ', "' + x + '")', 0); 
          //processNextChunk(c, t, s + p, p, x) 
         } 
         else { 
          $('#counter').html(''); 
         } 
        } 
       } 
       return true; 
      } 
     }); 
     return true; 
    } 

Répondre

2

Cela peut ou peut ne pas résoudre votre problème, mais vous ne devriez pas appellerez setTimeout avec un argument de chaîne.

Au lieu de cela, vous devez lui donner une fonction, comme ceci:

setTimeout(function() { 
    processNextChunk(c, t, s + p, p); 
}, 0); 

En outre, au lieu d'écrire $('#counter').html(''), vous pouvez écrire $('#counter').empty().

Pour résoudre votre problème, êtes-vous sûr que votre setTimeout appelle récursivement pour toujours?

+0

merci pour le conseil, j'ai maintenant ajouté la déclaration vide. Même lorsque j'ai supprimé la minuterie, j'éprouve le même problème. L'introduction de la minuterie était ma tentative d'empêcher la récursion, ce que je pensais être en train de se produire parce que le processusNextChunk s'appelle lui-même. –

+0

Ajout de la minuterie n'aiderait pas - il s'appelle toujours. Utilisez un débogueur pour parcourir votre code et vérifier s'il se répète pour toujours. – SLaks

+0

Le débogueur affiche le mot "vide" à côté d'une icône de bloc-notes sous le débogueur VS2008 pour chaque exécution de l'appel $ .ajax. Il en montre un pour chaque bloc de lignes demandé, et il arrête de les ajouter lorsqu'il n'y a plus de lignes. Cela implique qu'il ne s'agit pas d'une routine sans fin, mais que je ne suis peut-être pas en train de sortir de ma demande. –

0

Je ne peux pas dire exactement quelles données sont retournées dans le cas où vous avez récupéré toutes les lignes. Je suppose qu'il est censé faire échouer le chèque:

r = msg.d.substr(slash + 1, msg.d.length - slash); 

Si tel est le cas, vous pourriez être en mesure d'utiliser clearTimeout() dans votre clause else juste après:

$('#counter').html(''); 
+0

vous avez raison, la variable "r" est ce qui contient mon bloc de lignes.Avoir à annuler toutes les minuteries serait pénible car je devrais alors suivre tous les identifiants de minuterie, non? –

0

Vous appelez setTimeout (..., 0) alias un timeout nul. En d'autres termes, vous n'autorisez pas le navigateur à mettre à jour/redessiner. Notez que cela dépend du navigateur - certains tests effectués sur diverses machines au cours des années indiquent que winxp nécessite au moins un timeout de 50, alors que linux requiert un timeout de 10. Il semble que cela soit lié au temps minimum du système d'exploitation cédulaire

Si vous êtes sur une connexion rapide (par exemple: le développement localhost), peut-être l'appel ajax répond suffisamment rapide pour que la mise à zéro est un problème ...

Votre code semble que cela pourrait faire avec Il suffit d'augmenter le délai d'attente pour atteindre un temps plus long, disons 1 seconde, sans effets négatifs. [L'appel de setTimeout avec un argument de chaîne est parfaitement valide, mais il semble que vous ne citiez pas correctement. ]

+0

Les navigateurs déplacent la valeur du délai d'attente au minimum qu'ils peuvent gérer. Le délai d'expiration s'exécutera lorsque le thread en cours est terminé et tous les navigateurs seront actualisés entre les deux. Les valeurs de chaîne à timeout sont équivalentes à eval() et si elles ne sont pas invalides, tout simplement mauvaises pratiques. – Borgar

+0

J'ai essayé ceci, et ai également changé en utilisant un appel de fonction au lieu de la version d'eval, et cela n'a fait aucune différence. –

Questions connexes