2011-07-06 17 views
7

ACTUALIZACIÓN (5 de julio de 2013):¿Cómo evito la advertencia del script lento y forzo al navegador a continuar ejecutando el script hasta que finalice?

He aprendido mucho desde que originalmente esta pregunta. En uno de los comentarios a continuación, se sugirió que vuelva a enfocar la tarea y encuentre una manera de resolverla sin riesgo de bloquear la IU. Dije que era imposible, la función debe ejecutarse como está. Realmente no recuerdo lo que estaba tratando de lograr con la función, pero estoy seguro de que el comentarista tenía razón, y estaba equivocado. Si te tropiezas con esta pregunta y estás en una situación similar a la que yo tenía, considera seriamente la posibilidad de que tu enfoque sea defectuoso.

Es posible que también desee consultar web workers.

Here is where you can expect them to work.


pregunta original:

En lugar de ponerse demasiado específica a mi problema, voy a seguir esta genéricos para que otras personas que tropiezan con esto puede que le resulte útil.

Tengo una función que acepta un parámetro, una cadena. Si la cadena es corta, la función funciona bien y se completa de manera oportuna. Sin embargo, si la cadena que se transfiere es demasiado larga, la secuencia de comandos se ejecuta un poco, luego se agota el tiempo de espera y devuelve el diálogo de secuencia de comandos lenta del navegador que permite al usuario matar la secuencia de comandos.

Me gustaría evitar que esto suceda para que el script pueda continuar hasta su terminal.

¿Cómo se puede hacer esto?

Una nota al margen: si puedo hacer que esto funcione, también me gustaría hacer aparecer una barra de estado, similar a la que ves al cargar Gmail, para que el usuario sepa que están sucediendo cosas.

Gracias!

+5

Creo que necesita arregla tu función para que no tarde tanto. – lonesomeday

+0

Imposible. :-( –

+1

Luego tiene que hacerlo en otro lugar que no sea el navegador. Quizás podría transferir la función al idioma del lado del servidor al que está demandando. – lonesomeday

Respuesta

5

de ninguna manera se puede desactivar este comportamiento en cualquier navegador mediante la escritura. Imagine el impacto, deshabilite esa función y llame al while(1). Bastante mal.

Está en usted para crear código que no no bloquear el navegador por "demasiado tiempo". Hay muchos patrones de mejores prácticas. Siempre recomiendo tratar de dividir tu algoritmo en trozos más pequeños. Combine eso con un temporizador fuera de control y un bucle que asegure que cualquier operación no se ejecute durante más de 100 ms (por ejemplo).

var sequence = ['foo', 'bar', 'baz', 'base', 'ball', 'hello', 'world', '100k more'], 
    start = Date.now(); 

setTimeout(function _worker() { 
    do { 
     var element = sequence.shift(); 
     // do something with element 
    } while(sequence.length && (Date.now() - start < 100)); 

    if(sequence.length) 
     setTimeout(_worker, 25); 
}, 25); 
6

Puede intentar no bloquear completamente la IU y ejecutarla "en otra conversación" con setTimeout.

window.setTimeout(function() { ... code ... }, 0); 

digo "en otro hilo" porque no hay una verdadera multi-hilo en JS, y here es un artículo agradable sobre él


EDIT: (Para hacer que esta respuesta sea más UP- al día con las tecnologías web)

también puede utilizar HTML 5 Web Workers dependiendo de la browser you are targeting

+0

Por lo tanto, actualmente uso un bucle for para analizar cada carácter de la cadena. Lo sustituiré por un contador manual y un setTimeout y veré qué sucede. Espera ... ¿fue eso qué? ¿Estabas sugiriendo? –

+0

solo debes tener cuidado con los problemas de alcance al hacerlo :) –

+0

Sin dudas. Apreciar la ayuda. Te dejaré saber qué pasa. –

1

puede probar algunas cosas:

  1. función asíncrona usando setTimeout
  2. hacer su sueño función de vez en cuando para detener el bloqueo de la interfaz de usuario para el funcionamiento del tiempo largo (el infierno si es tan lento, se deja correr un poco más)
  3. el uso de JavaScript trabajadores alternativa a setTimeout, aquí es algunas google rápido para usted: http://ejohn.org/blog/web-workers/
1

Para eliminar la advertencia:

function setMaxScriptStatements(){ 

var WshShell = new ActiveXObject("WScript.Shell"); 
    WshShell.RegWrite ("HKCU\\Software\\Microsoft\\Internet Explorer\\Styles\\MaxScriptStatements", 1107296255, "REG_DWORD"); 
} 
3

A menos que su código es muy agresiva malo o malicioso, esto casi siempre ocurre exclusivamente en el IE 9 y a continuación cuando un script de inocente tiene bucles que tienen demasiado tiempo para ejecutar o una llamada AJAX se realiza a un servidor lento o hay una gran cantidad de datos que se devolverán y excede los límites permitidos.

Por lo tanto, usted podría conseguir sus usuarios a seguir un arreglo oficial de Microsoft para este problema aquí si realmente les molesta: http://support.microsoft.com/kb/175500 Si se lleva este Microsoft FixIT parche lo que aumenta su defecto MaxScriptStatements de las cuentas por defecto 5.000.000 hasta el máximo permitido (representado por el valor hexadecimal 0xFFFFFF que es igual a 4,294,967,295 declaraciones de ejecución totales) debe solucionar el problema, a menos que, como mencioné, el código sea particularmente malo o necesite una refactorización.

En resumen, las opciones son así:

  1. mejor solución - fix your script ...bucles de ruptura y/o recursividad detuvo después de N ejecuciones número, y asegurar peticiones AJAX son asynchronous not synchronous siempre que sea posible, especialmente en bucles

  2. truco alternativa - el uso HTML5 WebWorkers, pero es mejor usar WebWorker detection primero para ver si your browser les apoya, y utilizar una biblioteca WebWorker cuña como this o this si no es apoyado

  3. mediocre truco - setTimeout con unos bucles reales script execution Timer y dividiéndose en iteraciones, podría tener casos extremos que causan peor proble ms ...

  4. terribles truco - ActiveX registry writing, un mejor uso adecuado browser detection más feature detection

  5. mejor solución - Microsoft FixIT patch, si es sólo un pequeño subconjunto de usuarios, tiene ayuda de la tecnología enviarlos a la página oficial FixIT de Microsoft (o hágalo usted mismo) que agrega de manera más confiable las entradas de registro apropiadas para aumentar la cuenta de ejecución del script

Cuestiones relacionadas