2010-02-23 14 views
12

Necesito poder controlar el orden de los elementos que se procesan en el evento $(document).ready.
Se trata de controles múltiples, cargados desde varios archivos, todos pidiendo ser invocados en el evento ready. Todos comienzan una llamada asincrónica al servidor (AJAX). Solo después de que hayan terminado, necesito hacer un trabajo extra.

¿Cuál sería la solución elegante para esto?

+0

encontrado ReadyX en http://plugins.jquery.com/project/readyx Afirma que controla el orden. Pero no funcionará con 1.4.x ya que 'readyList' ya no está disponible. –

+0

Objetivamente, ¿cuál es su problema con mi solución? –

+0

No tiene nada de malo. Lo votó.Esperaba algo de soporte interno de jQuery. Algo así como ReadyList. Su solución funciona, pero requiere tocar todas las funciones involucradas. –

Respuesta

7

Solicitudes asíncronas incendio en orden, pero volverá en el orden en que lo completen primero. Por lo tanto, no existe una manera segura de obligarlos a terminar al mismo tiempo; sin embargo, puede crear reglas para ejecutar código solo después de que hayan regresado ciertos grupos.

Por ejemplo, defina una función de devolución de llamada con un conjunto de reglas, y páselo a cada devolución de llamada success para todas sus solicitudes ajax.

var completedObject = {}; 

function groupSuccessCallback() { 
    // Test for any combination of requirements 
    if (completedObject.ajax1 && completedObject.ajax2) { 
    ... // Do something that only requires 1 and 2 
    } 
    if (completedObject.ajax1 && completedObject.ajax2 && completedObject.ajax3) { 
    ... // Do something that requires all 3 being done 
     // your data is available at completedObject.ajax# 
    } 

    // Or test for _all_ entries for a dynamic count 
    var allComplete = true; 
    for(var i in completedObject) { 
    if (completedObject.hasOwnProperty(i) && !completedObject[i]) { 
     allComplete = false; 
    } 
    } 

    // Do whatchya need. 
    if (allComplete) { 
    alert("bb-b-bb-b-b-b-bbb... that's all folks!"); 
    } 
} 

continuación, establezca las banderas dentro de sus funciones de éxito:

// Ajax1 
completedObject['anything'] = false; // instantiate a dynamic entry in the object or use an array if you can't use names. 
$.ajax({ 
    ..., 
    ..., 
    success: function(data) { 
    completedObject['anything'] = data || true; 
    groupSuccessCallback(); 
    } 
}); 
+0

Esto es interesante. Pero tengo un número ** dinámico ** de controles que iniciarían estas solicitudes de sincronización. No puedo tener un 'si' estático. –

+0

Es un cambio de código menor ... Lo actualizaré. –

+0

Desde febrero de 2011, jQuery 1.5 tiene esta nueva oferta y promete cosas. Se adapta a este propósito. – Savageman

1

Dependiendo del resto de la página, hacer ese "trabajo adicional" en un controlador $.ajaxStop podría ser una opción más elegante.

Sin embargo, no sería apropiado si el usuario es capaz y/o es probable que active las siguientes llamadas $ .ajax() mientras que esas llamadas iniciales están en progreso. En ese caso, sus llamadas activadas manualmente pueden prolongar el evento $ .ajaxStop más allá de lo previsto.

+0

El problema tendré un número desconocido si eventos '$ .ajaxStop', ya que la página tiene un número dinámico de estos controles. –

+0

@Ron no necesariamente es cierto. $ .ajaxStop solo se activa después de que se completaron todas las llamadas ajax. Sin embargo, si se completa una llamada antes de que otra se ejecute, obtendría dos. –

+0

Esto todavía sería un problema. No puedo estar seguro de que todas las solicitudes comenzaron juntas. O que ninguno se completó antes de que todos comenzaran. –

0

Cree una variable que tenga un valor de 0. En la función de éxito de cada llamada Ajax incremente ese valor en 1 y compruebe si ese valor es igual a su número total de llamadas si ejecuta su función de compleción.

+0

@ Shog9 a la derecha. Podrías usar una variable ya que permanecería en el alcance todo el tiempo. – ctrlShiftBryan

2

John Resig el orden de evaluación de función en $ (document) ready:

Cada vez que una nueva función se agrega a la cola, es solo que se añade a una matriz - a continuación, siendo metimos retroceder nuevamente cuando se ejecuta. Avíseme si esto no ocurre para usted.

$ .readyList - sólo en pre 1.4 versiones

jQuery expone una propiedad llamada $.readyList, que es una matriz para permitir la función orded manipulación, sin embargo $.readyList in no longer publicly exposed in jQuery 1.4.0

manera Hackerish

puede intentar $(window).load(function() {});, se debe ejecutar después de que se haya cargado toda la ventana (no cuando el documento esté listo, como es con $(document).ready()

+0

Sí. pero se están agregando funciones a la cola desde diferentes controles en la página. Quiero asegurarme de que se está haciendo algo por última vez. Como un "finalmente" en una captura de prueba. –

+0

Sé acerca de 'readyList'. Estoy usando 1.4.2 –

Cuestiones relacionadas