2012-09-05 21 views
16

Tengo una situación en la que mis llamadas ajax deben realizarse en un orden particular. He usado objetos jQuery diferidos en otras situaciones, pero parece que no puedo encontrar una manera de hacer que esto se comporte de manera adecuada.jQuery objeto diferido con llamadas ajax anidadas

Tengo una función que realiza un número de solicitudes ajax en su vida. Algunas de las solicitudes se realizarán durante la devolución exitosa de otras solicitudes.

Mi pregunta es: ¿Hay alguna manera de devolver todos los objetos aplazados anidados a la llamada original $.when?

Un ejemplo simplificado sería:

function nestedAjax() { 
    $.get("/", function(){ 
     console.log("First ajax done."); 
     $.get("/", function(){ 
      console.log("Second ajax done."); 
     }); 
    }); 
}; 

Estoy tratando de tener la función nestedAjax utilizar $.when() y $.done() así:

$.when(nestedAjax()).done(function(){ 
    console.log("Complete"); 
});​ 

Con la lectura de salida de la consola:

> First ajax done. 
> Second ajax done. 
> Complete. 

I puede devolver el primer get para lograrlo:

> First ajax done. 
> Complete. 
> Second ajax done. 

Pero obviamente esto no es lo que requiero. Cualquier ayuda sería apreciada.

+0

si tienen que ocurrir en secuencia, por qué no realizar solicitudes sincrónicos en el primer lugar? Deja de tratar de caber una clavija cuadrada en un agujero redondo. –

+0

Tienes razón. Gracias por la llamada despertador. Logré reorganizar y lograr mi funcionalidad deseada. Todavía estoy interesado, sin embargo, si hay una forma de 'recopilar' objetos diferidos de las llamadas ajax anidadas para su evaluación, por lo que mi pregunta sigue en pie. – Aesthete

+0

Eso es justo. :) Puede que no esté fuera de la base aquí - es muy tarde y he estado trabajando - ¿pero quizás en la función de devolución de llamada de cada llamada AJAX podría agregar el objeto a una matriz? Podría pasar la matriz a través de la cadena como argumento o dejarla en el espacio global. –

Respuesta

14

En realidad es bastante simple. Aunque todas las llamadas AJAX son objetos Diferidos, aún utilizo uno para el método en sí.

function nestedAjax() { 
    var dfd = $.Deferred(); 
    $.get("/echo/json/", function(){ 
     console.log("First ajax done."); 
     $.get("/echo/json/", function(){ 
      console.log("Second ajax done."); 
      dfd.resolve(); 
     }); 
    }); 

    return dfd.promise(); 
}; 
+0

Gracias, los he usado con más frecuencia y ahora veo por qué no puedo hacer exactamente lo que estaba tratando de hacer. Gracias por la ayuda. – Aesthete

+0

por supuesto !! He estado golpeando mi cabeza contra el diferido por unas horas, pero no hice la conexión. gracias Dr. !! – Doga

+0

-1 por errores de manejo. La respuesta de Check @ dmnd. – Bergi

1

No se pudo agregar un comentario por alguna razón a la respuesta anterior.

Así que añado mi comentario aquí. La respuesta anterior solo funcionará si las llamadas ajax son rápidas y regresa ANTES del retorno dfd.promise().

Tengo el mismo problema. Y como puedes ver El objeto diferido devuelto indica que está "pendiente": http://jsfiddle.net/BtEKa/

+0

Sí, tienes toda la razón. Esto es algo que había concluido, y en mi situación tengo varias solicitudes de AJAX que se desempeñan en la misma función. La solución más cercana a mis problemas fue usar '$ .ajaxComplete()', aunque rediseñé mi enfoque y lo hice funcionar limpiamente. – Aesthete

+0

Pero tenga en cuenta que si lo deja así. El evento se activará eventualmente después de que el objeto se haya resuelto/rechazado. Ese fue mi problema. Mi objeto devolvió un estado "pendiente"() ... el par de segundos más tarde cambió y mis eventos comenzaron a dispararse. – Juw

+0

En python existe la capacidad de 'producir' un resultado de una estructura de control. Esto parece ser lo que necesitaría, donde múltiples llamadas ajax podrían arrojar un resultado y al recibir todos los resultados, se podría resolver un objeto diferido 'maestro'. Es obvio que pelear un idioma para obtener cierto comportamiento de él suele ser una señal de que es necesario rediseñar el enfoque. – Aesthete

6

No necesita realmente un objeto diferido adicional. Puede hacer lo que quiera encadenando con then():

function nestedAjax() { 
    return $.get("/echo/json/").then(function(result1){ 
     console.log("First ajax done."); 
     if (result1) { 
      return result1; 
     } else { 
      return $.get("/echo/json/").then(function(nestedResult){ 
       console.log("Second ajax done."); 
       return nestedResult; 
      }); 
     } 
    }); 
}; 

he añadido algo de lógica ya que creo que es probablemente la razón por la que se está ejecutando esta forma sincrónica. Después de que se puede utilizar el resultado en $.when así:

$.when(nestedAjax(), $.get("/something/else")).then(function(nested, other) { 
    console.log("Complete.", nested, other); 
}); 
+0

No consigo el if/else aquí. ¿Eso evitaría que se emita la segunda llamada? Explique. – Cymbals

+1

Sí, la segunda llamada Ajax solo se emitirá si el resultado de la primera es verdad. – dmnd

+1

@dmnd: Creo que quiso decir "si el resultado del primero es falso". –

Cuestiones relacionadas