2009-12-11 16 views
14

Estoy desarrollando JS que se usa en un marco web, y frecuentemente se mezcla con el código jQuery de otros desarrolladores (a menudo propenso a errores). Lamentablemente, los errores en sus bloques jQuery (documento) .pready impiden que se ejecute. Tomemos el siguiente ejemplo sencillo:Manejo de errores en jQuery (documento) .ready

<script type="text/javascript"> 
    jQuery(document).ready(function() { 
     nosuchobject.fakemethod();  //intentionally cause major error 
    }); 
</script> 
<script type="text/javascript"> 
    jQuery(document).ready(function() { 
     alert("Hello!");     //never executed 
    }); 
</script> 

no deberían ejecutar el segundo bloque listo independientemente de lo que ocurrió en el anterior? ¿Existe una forma "segura" de ejecutar jQuery (documento). ¿Ya se ejecutará incluso en el caso de errores previos?

EDITAR: No tengo control/visibilidad sobre los bloques propensos a errores, ya que están escritos por otros autores y se mezclaron de forma arbitraria.

Respuesta

13

No he probado este código, pero debería funcionar (al menos, la idea debe de todos modos). Asegúrese de incluirlo DESPUÉS de jquery, pero ANTES de cualquier secuencia de comandos con errores potenciales. (No es necesario, ver los comentarios.)

var oldReady = jQuery.ready; 
jQuery.ready = function(){ 
    try{ 
    return oldReady.apply(this, arguments); 
    }catch(e){ 
    // handle e .... 
    } 
}; 
+0

Esto parece funcionar bastante bien, independientemente de si va antes o después de las secuencias de comandos con errores potenciales. Creo que lo que haré es mover el contenido de mi bloque listo (alerta ("¡Hola!") En la muestra) justo después del bloque catch. De esa forma mi bloque listo puede "agregarse" al final de los bloques listos anteriores. – 3hough

+0

Gran solución. Ni siquiera pensé en eso. –

+0

No estoy seguro de lo que estaba pensando, pero esto funcionará sin importar a dónde vaya, siempre y cuando esté en la etiqueta y no en algún evento de carga, ya que secuestramos el método listo antes de invocarlo en la carga dom. – jvenema

1

¿Ha intentado ajustar los comandos propensos a errores en try ... catch brackets?

$(function(){ 
    try { 
     noObject.noMethod(); 
    } catch (error) { 
     // handle error 
    } 
}); 

$(function(){ 
    try { 
     alert("Hello World"); 
    } catch (error) { 
     // handle error 
    } 
}); 

para evitar posibles confusiones, $(function(){ ... }); es funcionalmente el mismo que $(document).ready(function(){ ... });

+0

El problema es que no tengo el control/visibilidad sobre los bloques que arrojan los errores. En el ejemplo anterior, el primer bloque jQuery (documento) .ready proviene del código de otra persona. Por lo tanto, desafortunadamente no tengo una forma de envolverlos en try/catch blocks. Esto es parte de un marco web donde los complementos arbitrarios pueden cargarse juntos en el encabezado del documento. – 3hough

+2

Debe mencionar en su pregunta que no tiene acceso a su código. – Sampson

-2

Usted podría volver a referenciar jQuery antes de cada uno de los bloques de código. Su código usaría la instancia nueva de la biblioteca y se ejecutaría. He probado esto en Safari 4.0.3 en OSX.

<html> 
<head> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script> 
    <script type="text/javascript"> 
     jQuery(document).ready(function() { 
            nosuchobject.fakemethod();       //intentionally cause major error 
        }); 
    </script> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>  
    <script type="text/javascript"> 
        jQuery(document).ready(function() { 
            alert("Hello!");                 //executed! 
        }); 
    </script> 

</head> 
<body> 

<p>hello world</p> 

</body> 
</html> 
+0

Idea terrible ... esto al menos obligará al usuario a descargar la biblioteca dos veces, y también podría causar problemas con las variables estáticas y los objetos que se sobrescriben. – jvenema

+0

El navegador del usuario solo vuelve a descargar el archivo remoto cuando se coloca un buster de caché.En mi ejemplo, el navegador lee la segunda referencia de jQuery desde el caché. No es bonito, pero ayuda a resolver el problema original. En cuanto a los problemas con variables estáticas y objetos, ¿quiere decir dentro de la biblioteca jQuery en sí misma, o variables y objetos estáticos definidos por el usuario? En caso de sobreescritura, jQuery se correlaciona consigo mismo. En mi ejemplo, el segundo bloque escrito correctamente haría referencia a la nueva instancia de jQuery. ¿Puede explicar los problemas que menciona? ¡Gracias! – simeonwillbanks

+0

Justo al comienzo de jquery, verá esto: jQuery.fn = jQuery.prototype = {...}. Como esos objetos no se extienden sino que se crean instancias, todo lo que modifica o toca esas propiedades (y de hecho, cualquier otra cosa establecida estáticamente en el nivel jquery) se descartará. E incluso si el navegador guardó en caché el js, aún tendrá que volver a analizarlo y volver a cargar todos los elementos declarados, degradando la experiencia del usuario (sin mencionar que probablemente introduzca fugas de memoria porque no hay limpieza de ningún dom eventos). – jvenema

2

Para responder a su pregunta, tanto de los bloques ready se combinan en una sola esencia dada la forma en que funciona jQuery:

<script type="text/javascript"> 
    jQuery(document).ready(function() { 
     nosuchobject.fakemethod();  //intentionally cause major error 
     alert("Hello!");     //never executed 
    }); 
</script> 

Así que por eso no es de alerta por el error anterior. No creo que haya una forma de arreglar esto para que cada función ready se ejecute independientemente de fallas anteriores.

1

Aquí está la solución, que se ajustará a cualquier función enviado listo con bloque try-catch:

(function($){ 
    $.fn.oldReady = $.fn.ready; 
    $.fn.ready = function(fn){ 
     return $.fn.oldReady(function(){ try{ if(fn) fn.apply($,arguments); } catch(e){}}); 
    } 
})(jQuery); 
Cuestiones relacionadas