when then done await async another after jquery jquery-deferred promise

then - jquery aplazó la falla de giro en éxito



jquery promise ajax (4)

Podría compilar $.onFailSucceed bastante facilidad al envolver el objeto $.Deferred :

$.onCompleteSucceed = function(oldDfd) { var newDfd = $.Deferred(); oldDfd.always(newDfd.resolve); return newDfd.promise(); }

A continuación, puede ajustar las llamadas apropiadas en este método:

$.when( a.ajax(), $.onCompleteSucceed(b.ajax()), c.ajax() ).then(...)

Entonces al usar jQuery diferido y $.when para cargar muchos objetos en paralelo.

$.when( a.ajax(), b.ajax(), c.ajax() ).then( //do something when all are complete complete(); );

Ahora, b.ajax() algunas veces fallará, pero en realidad no me importa. Solo quiero esperar hasta que todas las llamadas se hayan completado antes de llamar a complete ().

Desafortunadamente, tan pronto como b falla, when() rechaza y nunca dispara la devolución de llamada then() . Este es el comportamiento esperado de AFAIK para $.when() , sin embargo, dosent me conviene en este caso.

De hecho, quiero una manera de decir:

$.when( a.ajax(), b.ajax().fail(return success), c.ajax() ).then(...)

¿O tal vez hay una forma diferente de usar when() , o una construcción más adecuada?


Aquí hay algo mejor que hackear una falla en un éxito.

Hecho poco conocido, $ .when () ejecutará la devolución de llamada then () inmediatamente si cualquiera de los parámetros falla. Es por diseño. Para citar la documentación:

http://api.jquery.com/jQuery.when/

En el caso de Deferidos múltiples donde se rechaza uno de los Deferidos, jQuery.when inmediatamente activa los failCallbacks para su maestro 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 realidad, no hay una forma integrada de esperar hasta que todos estén terminados, independientemente de su estado de éxito / falla.

Entonces, construí $ .whenAll () para ti :) Siempre espera hasta que todos resuelvan, de una forma u otra:

http://jsfiddle.net/InfinitiesLoop/yQsYK/


Si desea capturar el error de una promesa y convertirla en un éxito, puede usar el failFilter de entonces para devolver una promesa resuelta, como sigue:

deferredCall.then(function(answer) { // this is success. you might transform the answer here. return transformed; }, function() { // this is a fail. you might resolve the fail with an empty object. return $.Deferred().resolve({}).promise(); });

Hacer esto asegurará que la cadena pueda continuar intacta después de la falla.

Entonces, para su ejemplo, puede hacer esto:

$.when([ a.ajax(), b.ajax().then(function(answer) { return answer; }, function() { return $.Deferred().resolve({}).promise(); }), c.ajax() ]).then(function(results) { // etc. });

Ejemplo 2: en mis aplicaciones, a veces uso para obtener datos relacionales para una entidad en particular y tengo en cuenta la posibilidad de que un 404 indique que no existe tal relación:

getEntity(id).then(function(entity) { return getAssociation(id).then(function(association) { entity.association = association; return entity; }, function() { entity.association = null; return $.Deferred().resolve(entity).promise(); }); }).done(function(entity) { // etc. });

Tenga en cuenta que las respuestas anteriores sugieren usar el método de la tubería . Este método está en desuso a partir de jQuery 1.8.