Quiero hacer tres llamadas ajax en un evento de clic. Cada llamada ajax realiza una operación distinta y devuelve los datos necesarios para una devolución de llamada final. Las llamadas en sí no dependen una de la otra, todas pueden ir al mismo tiempo, sin embargo, me gustaría tener una devolución de llamada final cuando las tres estén completas.
$('#button').click(function() {
fun1();
fun2();
fun3();
//now do something else when the requests have done their 'success' callbacks.
});
var fun1= (function() {
$.ajax({/*code*/});
});
var fun2 = (function() {
$.ajax({/*code*/});
});
var fun3 = (function() {
$.ajax({/*code*/});
});
Respuestas:
Aquí hay un objeto de devolución de llamada que escribí donde puede configurar una devolución de llamada única para que se active una vez que esté completa o dejar que cada una tenga su propia devolución de llamada y dispararlas todas una vez que estén completas:
AVISO
Desde jQuery 1.5+ puede usar el método diferido como se describe en otra respuesta:
Ejemplo de diferido aquí
para jQuery <1.5 lo siguiente funcionará o si necesita que se activen sus llamadas ajax en momentos desconocidos, como se muestra aquí con dos botones: se activa después de hacer clic en ambos botones
[uso]
para devolución de llamada única una vez completada: ejemplo de trabajo
cada uno tiene su propia devolución de llamada cuando todo está completo: ejemplo de trabajo
[El código]
fuente
setCallback
para agregar más a la cola. Aunque ahora que lo pienso ... debería llamarloaddCallback
o algo por el estilo ... y no solo configurarlo, ya que se está agregando a la colasingleCallback
innecesaria la variable en la segunda línea? ¿O me estoy perdiendo algo?Parece que tiene algunas respuestas a esto, sin embargo, creo que hay algo que vale la pena mencionar aquí que simplificará enormemente su código. jQuery presentó el
$.when
en v1.5. Parece que:No lo vi mencionado aquí, espero que ayude.
fuente
No veo la necesidad de ningún objeto malarky yo mismo. Simple tiene una variable que es un número entero. Cuando inicie una solicitud, incremente el número. Cuando uno complete, decremente. Cuando es cero, no hay solicitudes en curso, así que ya está.
fuente
if (!--inProgress)
. La versión correcta es análoga ainProgress = inProgress - 1; if (inProgress == 0) { /* do stuff */ }
. La forma compacta combina el operador de decremento de prefijo (--
) y el operador de negación (!
) para evaluar a "verdadero" (y, por lo tanto, ejecutar elif
bloque), si la disminucióninProgress
da como resultadoinProgress == 0
, y se evalúa como "falso" (y por lo tanto no hace nada) de lo contrario.Vale la pena señalar que, dado que
$.when
espera que todas las solicitudes de ajax sean argumentos secuenciales (no una matriz), comúnmente se$.when
usarán.apply()
así:Esto se debe a que
$.when
acepta argumentos como esteY no así:
fuente
all
método o algo similar, pero me gusta el concepto de mapa. Agradable.Me gusta la idea de hvgotcodes. Mi sugerencia es agregar un incrementador genérico que compare el número completo con el número necesario y luego ejecute la devolución de llamada final. Esto podría integrarse en la devolución de llamada final.
[Editado para reflejar actualizaciones de nombres.]
fuente
EDITAR: tal vez la mejor opción sería crear un punto final de servicio que haga todo lo que hacen las tres solicitudes. De esa manera, solo tiene que hacer una solicitud, y todos los datos están donde los necesita en la respuesta. Si descubres que estás haciendo las mismas 3 solicitudes una y otra vez, probablemente quieras seguir esta ruta. A menudo es una buena decisión de diseño establecer un servicio de fachada en el servidor que agrupe las acciones de servidor más pequeñas que se usan juntas. Solo una idea.
Una forma de hacerlo sería crear un objeto de 'sincronización' en su controlador de clics antes de que llame el ajax. Algo como
La sincronización estará vinculada al alcance de las llamadas exitosas automáticamente (cierre). En el controlador de éxito, incrementa el recuento y, si es 3, puede llamar a la otra función.
Alternativamente, podrías hacer algo como
cuando se ejecuta cada éxito, cambiaría el valor de la sincronización a verdadero. Tendría que verificar la sincronización para asegurarse de que las tres son verdaderas antes de continuar.
Tenga en cuenta el caso en el que uno de sus xhrs no devuelve el éxito; debe tenerlo en cuenta.
Otra opción sería llamar siempre a la función final en sus controladores de éxito y hacer que acceda a la opción de sincronización para determinar si realmente debe hacer algo. Sin embargo, deberá asegurarse de que la sincronización esté dentro del alcance de esa función.
fuente
Hice la misma pregunta hace un tiempo y obtuve un par de buenas respuestas aquí: la mejor manera de agregar una 'devolución de llamada' después de una serie de llamadas XHR asincrónicas
fuente
Obtuve algunas buenas sugerencias de las respuestas en esta página. Lo adapté un poco para mi uso y pensé que podría compartirlo.
Aquí hay algunas limitaciones, pero para mi caso estuvo bien. También descubrí que para cosas más avanzadas también hay un complemento AOP (para jQuery) que podría ser útil: http://code.google.com/p/jquery-aop/
fuente
Encontré este problema hoy, y este fue mi intento ingenuo antes de ver la respuesta aceptada.
fuente
No es jquery (y parece que jquery tiene una solución viable) sino simplemente como otra opción ...
He tenido problemas similares al trabajar mucho con los servicios web de SharePoint: a menudo necesita extraer datos de múltiples fuentes para generar entradas para un solo proceso.
Para resolverlo, incorporé este tipo de funcionalidad en mi biblioteca de abstracción AJAX. Puede definir fácilmente una solicitud que activará un conjunto de controladores cuando se complete. Sin embargo, cada solicitud se puede definir con múltiples llamadas http. Aquí está el componente (y documentación detallada):
DPAJAX en DepressedPress.com
Este simple ejemplo crea una solicitud con tres llamadas y luego pasa esa información, en el orden de las llamadas, a un único controlador:
Tenga en cuenta que, a diferencia de muchas de las otras soluciones (incluida, creo que la solución "cuándo" en jquery) siempre que este método no fuerce el enhebrado de las llamadas que se realizan, cada una seguirá funcionando tan rápido (o tan lentamente) como lo permita el entorno pero el controlador único solo se llamará cuando todos estén completos. También admite la configuración de valores de tiempo de espera e intentos de reintento si su servicio es un poco inestable.
Lo he encontrado increíblemente útil (e increíblemente simple de entender desde la perspectiva del código). No más encadenamiento, no más conteo de llamadas y ahorro de salida. Solo "configúralo y olvídalo".
fuente
Ok, esto es viejo pero déjame aportar mi solución :)
Funciona también con funciones que tienen una devolución de llamada. Establece syncCount y llama a la función sync (...) en la devolución de llamada de cada acción.
fuente
Encontré una manera más fácil de hacerlo sin la necesidad de métodos adicionales para organizar una cola.
JS
PHP (ajax1.php)
PHP (ajax2.php)
fuente
Por defecto, todas las solicitudes se envían de forma asincrónica (es decir, esto se establece en verdadero de forma predeterminada). Si necesita solicitudes sincrónicas, configure esta opción en
false
. Las solicitudes de dominio cruzado y lasdataType: "jsonp"
solicitudes no admiten operaciones sincrónicas. Tenga en cuenta que las solicitudes sincrónicas pueden bloquear temporalmente el navegador, deshabilitando cualquier acción mientras la solicitud está activa. A partir de jQuery 1.8 , el uso deasync: false
con jqXHR ($.Deferred
) está en desuso; debe utilizar las opciones de devolución de llamada correcta / errónea / completa en lugar de los métodos correspondientes del objeto jqXHR , como por ejemplo,jqXHR.done()
o el obsoletojqXHR.success()
.fuente
Lo siento, pero no puedo explicar lo que sé porque soy coreano y no puedo hablar ni una palabra en inglés. pero creo que puedes entenderlo fácilmente.
fuente