9
votes

Définition de la limite d'expiation JavaScript dans Google Chrome

est-il possible d'augmenter la limite de délai de sortie pour JavaScript?

Si j'ai un script qui s'exécute pendant plus de 20/30 secondes, Chrome sera contextuel avec la boîte de dialogue de page qui ne répondra pas.

Faire un script plus efficace ne m'aidera pas parce que le script doit parfois faire ierra une fonction pendant un million ou un milliard de fois


7 commentaires

Puis-je vous demander pourquoi vous Besoin en boucle sur une fonction de milliard de fois? J'ai l'impression que la solution à ce problème réside dans l'optimisation de votre algorithme plutôt que d'augmenter les délais.


Je calcule les chances d'obtenir différentes mains de poker, qui avec 5 cartes sont de 2598960 possibilités que j'ai besoin de boucler.


Alors, plutôt que de boucler sur toutes ces possibilités, pourquoi ne pas appliquer certaines propriétés de statistiques simples / formules? Il semble que vos calculs puissent faire bonne utilisation de la addition , multiplication et des formules de probabilité conditionnelles en particulier.


Je ne suis pas si bon en maths et je laisse l'utilisateur choisir quelles cartes sont connues et combien de cartes au total


Ah, je vois. Eh bien, si vous souhaitez que beaucoup de gens utilisent cela, vous devriez certainement effectuer des recherches sur des méthodes mathématiques, car elles seront beaucoup plus efficaces, utilisent des pistes de hack-hack-circonfères et offrent une meilleure expérience globale. Peut-être que cette page serait utile pour vous: STATS.GLA. AC.UK/STEPS/Glossary/probability.html#CondPROB


Cela doit-il fonctionner dans IE? Si vos utilisateurs peuvent utiliser FF / Chrome / Safari, vous devez utiliser des travailleurs Web, au lieu du piratage que nous avons suggéré. ejohn.org/blog/web-workers


Nope, il n'a pas à travailler dans IE uniquement Google Chrome


3 Réponses :


6
votes

Pour diviser la fonction sur les étapes / les morceaux et exécuter ceux-ci à l'intérieur setInterval (fonction () {}) code>. Cette page sera réactive, vous pourrez informer l'utilisateur de l'avancement de l'exécution et vous ferez votre travail.

update strong>: Voici une fonction simple qui prend travailleur code> fonction exécutant chaque itération, chunksz code> - Nombre d'itérations fonctionnant en un seul morceau Maxit Code> - Nombre total d'itérations. P>

function loopBody(i){ ... do something ... }
task(loopBody,100, 100000);


15 commentaires

Voir le commentaire sur ma propre réponse, et j'ai besoin de la boucler dans le bon ordre, donc je ne peux pas utiliser 'seinterval (fonction () {})', mais je l'utilise au début du calcul.


Je pense qu'il dit qu'il dise de briser la boucle en morceaux gérables. Donc, si vous avez déjà bouclées 10 000 fois, appelez Sintinval () pour laisser le navigateur savoir que quelque chose se passe toujours. Donc, avec chaque boucle, vous pourriez incrémenter un compteur. Ensuite, chaque fois que votre comptoir atteint 10 000, réinitialisez le compteur et appelez à nouveau SERNERVAL ().


Je reçois l'idée, mais je ne sais pas comment appliquer cela à une fonction récursive


@TyLo: Il n'y a pas de fonction récursive là-bas. Voir ma mise à jour2.


@ C-SMILE: Ce n'est peut-être pas une récursion de la pile, mais c'est un type de récursivité, une fonction qui finit par se rapprocher jusqu'à ce qu'elle soit terminée. La seule différence est que cela se fait avec un délai d'attente.


@Juan Mendes: C'était une réponse sur "Je ne sais pas comment appliquer cela à une fonction récursive" - ​​la fonction de travailleur n'est pas récursive en soi.


@ C-SMIME - Votre fonction d'excellente tâche () n'est pas récursive (du moins non pas par la définition que j'utiliserais), mais peut-être que Tyilo signifiait que sa fonction originale utilise la récursion et elle ou elle est Je ne sais pas comment faire ce travail avec votre algorithme de chunking.


@nnnnnn: la tâche () devrait également fonctionner à des cas récursifs. Je ferais un comptage d'itération Common pour toutes les invocations () pour de tels scénarios. Je l'ai laissé comme un exercice pour le lecteur. En passant, de tels cas peuvent être traités naturellement en utilisant le rendement s'il a été mis en œuvre par tous les UA.


Dis que je veux faire cela avec votre code: Fonction RecursiveFunction (Profondeur, Num) {if (Profond == 10) {Console.log (Nums); revenir; } pour (var a = num; a <10; a ++) {nums [profondeur] = A; Frotchfunction (Profondeur + 1, A); }} var nums = []; RecursiveFunction (0, 0);


@Tyilo: J'ai essayé de mettre en œuvre votre fonction récursive avec tâche mais cela ne signifie pas grand sens pour moi, pouvez-vous publier un exemple réel de la fonction récursive que vous souhaitez exécuter (ajouter une documentation pour expliquer quoi C'est censé faire) et comment tu l'appelles? Ne le postez pas comme un commentaire comme vous l'avez fait ci-dessus, créez un jsfiddle.net . @ C-Smile: J'ai ajouté une mise en œuvre de SumofsQuars à l'aide d'une tâche , voir ma réponse.


@Tyilo: Vous devez publier quelque chose qui fonctionne ... Ce que vous avez posté ne fait rien et que vous le savez, des globaux manquants. Si votre fonction est trop compliquée, vous devez créer une réduction et la publier. Veuillez documenter votre code si cela prend trop de temps pour comprendre, je ne peux pas vous permettre de vous aider.


@Tyilo, j'ai essayé quelque chose, il n'est toujours pas clair que votre fonction est censée faire, mais essentiellement, vous devez appeler la fonction récursive avec un délai d'attente. Puisque je ne sais pas ce que votre fonction est censée faire, je ne sais pas si le comportement a été affecté. Testez-le et laissez-moi savoir de tout problème jsfiddle.net/mendesjuan/9hkpb/1 Au fait, je pense que l'ajout @juan Mendes fait qu'il en informait la personne qu'il y a un commentaire qui leur intéresse.


@Tyilo: gars drôle, votre fonction n'a pas de sens pour moi, je sais que cela n'a pas donné les mêmes résultats, mais je ne vais pas passer du temps à déboguer pourquoi ce n'est pas le cas. Aviez-vous correctement documenté votre fonction quant à ce qu'il est censé faire, peut-être que j'aurais peut-être changé plus de la logique pour obtenir le bon résultat. Dans tous les cas, cet exemple vous donne suffisamment de points de vue sur la façon de casser vos calculs avec des délais d'attente


Nope, pas lorsque vous travaillez avec des fonctions récursives + pour les boucles + variables globales


@Tyilo: Au fait, la récursion avec les globaux semble vraiment fausse



3
votes

Lorsque vous avez beaucoup de traitement à faire du côté du client, vous devez diviser votre travail en threads séparés. Le navigateur n'a qu'un seul thread pour la manipulation des entrées utilisateur (événements) et pour le traitement de JS. Si vous traitez trop de JS, sans céder, l'interface utilisateur devient insensible et le navigateur n'est pas heureux.

Comment pouvez-vous permettre à votre script de céder? La nouvelle façon est d'utiliser des travailleurs Web http://www.whatwg.org/ Spécifications / travailleurs Web / travail actuel / . Cela fonctionne en créant un thread séparé pour exécuter votre JS, le fil de thread n'accède pas à la DOM et peut être exécuté simultanément. P>

Cependant, cette nouvelle technologie n'existe pas dans tous les navigateurs. Pour les navigateurs plus anciens, vous pouvez diviser votre travail en l'appelant au script par des délais d'attente. Chaque fois qu'un délai d'attente se produit, le script cède au navigateur pour exécuter ses événements, une fois le navigateur terminé, votre prochain délai d'attente sera déclenché. P>

strong> http://jsfiddle.net/mendesjuan/pucxf/ p> xxx pré>

L'exemple sur Jsfiddle a commenté l'appel synchrone, vous pouvez le remettre pour voir le navigateur de ramper. Notez que l'appel asynchrone prend beaucoup de temps à compléter, mais cela ne provoque pas le message de script à long terme et il vous permet d'interagir avec la page tout en calculant (sélectionnez le texte, les effets sur le bouton). Vous pouvez le voir imprimer des résultats partiels sur le volet en bas à droite. P>

update strong> http://jsfiddle.net/mendesjuan/pucxf/8/ p>

Essayons d'utiliser la fonction de tâche de C-Smile pour implémenter la somme des carrés. Je pense qu'il manque un paramètre, une fonction à rappeler lorsque la tâche est terminée. Utilisation de Task Code> nous permet de créer plusieurs fonctions chuntées sans dupliquer les travaux d'appel de SettimeOUT et de l'itération. P>

/**
 * @param {function} worker. It is passed two values, the current array index, 
 *        and the item at that index
 * @param {array} list Items to be traversed
 * @param {callback} The function to call when iteration is finished;
 * @param {number} maxit The number of iterations of the loop to run 
 *        before yielding, defaults to 1000
 */
function task(worker, list, callback, maxit)
{
  maxit = maxit || 1000; 
  var idx = 0;
  exec_chunk();
  function exec_chunk() 
  {
     for(var n = 0; n < maxit; ++n)
     {
       if(idx >= list.length) {
         callback(); 
         return;
       }
       worker(idx, list[idx]);
       idx++;
     }
     setTimeout(exec_chunk,1);
  }
}


function sumOfSquaresAsync(list, callback) 
{
   var total = 0;

   // The function that does the adding and squaring
   function squareAndAdd(index, item) {
      total += item * item;
      // DOM manipulation to make it take longer and to see progress
      var node = document.createElement("div");
      node.innerHTML = "Async temp value = " + total;
      document.body.appendChild(node);                
   }

   // Let the caller know what the result is when iteration is finished
   function onFinish() {
      callback(total);
   }

   task(squareAndAdd, list, onFinish);

}

var list = [];
for (var i = 0; i < 100000; i++) {
   list.push(Math.random());
}

sumOfSquaresAsync(list, function(total) {
    console.log("Sum of Squares is " + total);        
})


0 commentaires

3
votes

Si votre objectif est de supprimer le message "Kill-Wait" en tant que solution temporaire rapide pour votre JavaScript lent, la solution consiste à ouvrir des outils Outils / développeurs dans Google Chrome et de le garder ouvert et minimisé quelque part sur votre bureau tout en naviguant. < / p>


0 commentaires