2011-04-26 12 views
9

imaginar un escenario en el que queremos hacer algo después de las solicitudes concurrentes para 'foo' y 'bar' han completado con éxito, o informar de un error si uno o ambos de ellos falla:jQuery cuando/then/fail con solicitudes concurrentes de ajax: ¿Qué solicitud falló?

$.when($.getJSON('foo'), $.getJSON('bar')) 
    .then(function(foo, bar) { 
    console.log('I fire if BOTH requests are successful!'); 
    }) 
    .fail(function() { 
    console.log('I fire if one or more requests failed.'); 
    }); 

¿Cómo puedo determinar si 1) la solicitud de 'foo' falló, o 2) la solicitud de 'barra' falló, o 3) si ambas fallaron?

+0

has necesitado sólo hacer uno a la vez? – locrizak

+0

@locrizak - Imagine una aplicación que solicita 'foo' y 'bar' al mismo tiempo, pero necesita que ambos vuelvan con éxito antes de procesarlos. – Javier

+0

¿Por qué no hacer que tanto foo como la barra devuelvan verdadero o falso dependiendo de su éxito o fracaso, llame a ambas funciones y guarde sus devoluciones en variables separadas? de esa manera puede exigir que ambos sean ciertos y, de no ser así, verificar cuál de los dos era falso. – eagerMoose

Respuesta

10

Basta con añadir una llamada fallará a cada promesa que se devuelve desde $.getJSON:

function make_error_handler(msg) { 
    return function() { console.log(msg); }; 
} 

$.when($.getJSON('foo').fail(make_error_handler("foo failed")) 
      , $.getJSON('bar').fail(make_error_handler("bar failed"))) 
    .then(function(foo, bar) { 
    console.log('I fire if BOTH requests are successful!'); 
    }) 
    .fail(function() { 
    console.log('I fire if one or more requests failed.'); 
    }); 

Si necesita más control de grano fino se puede sobrecargar $.getJSON para devolver información adicional a la función a prueba - consulte la documentación de jQuery en deferred.rejectWith

0

se podría llamar .isResolved() para comprobar si una solicitud hizo realidad completa, pero el problema con .when() es que va a fallar tan pronto como sea petición falla, por lo que puede' t confiable decir si la otra solicitud podría estar a punto de fallar.

creo the answer I just posted a un similar question resolverá (sin doble sentido) este requisito, mediante la creación de un extra $.Deferred para cada consulta AJAX, lo que le permite esperar hasta que se conoce el resultado real de ambas llamadas AJAX.

1

De the documentation on jQuery.when

En el caso-Deferreds múltiples, donde se rechaza una de las Deferreds, jQuery.when se activa inmediatamente los failCallbacks para su amo Diferido. Tenga en cuenta que algunos de los aplazados aún no se han resuelto en ese momento. Si necesita realizar un procesamiento adicional para este caso, como cancelar cualquier solicitud ajax sin terminar, puede mantener referencias a los objetos jqXHR subyacentes en un cierre e inspeccionarlos/cancelarlos en failCallback.

En otras palabras, se supone que debe mantener las referencias a cada solicitud y verificarlas manualmente usted mismo, si es necesario.

La dificultad es que cuando la devolución de llamada falla se llama, de cualquier número de diferidos, pueda todavía ser excepcional , por tanto, en ese estado no tienen ni fracasado ni tenido éxito.

Deseo que la documentación explicada sea un poco mejor en cuanto a lo que se pasa al manejador de errores en este caso. A juzgar por el código fuente, sin embargo, parece que los argumentos recibidos por los manipuladores de fallar dependen de qué diferido falla en primer lugar:

args[ i ].promise().then(resolveFunc(i), deferred.reject); 

No soy un experto en el funcionamiento interno de jQuery, pero creo que esto simplemente le permite a cada uno de sus de diferidos llame al método "maestro" Deferred reject con los argumentos que normalmente pasaría a sus manejadores. No es ideal, si me preguntas ... pero entonces podría estar malinterpretando esto.

me pregunto si se referían a esto, sin embargo:

args[ i ].promise().then(resolveFunc(i), func() { deferred.reject(args); }); 
Cuestiones relacionadas