2011-06-30 19 views
47

Tengo una cadena profunda de tres capas de llamadas ajax diferidas, e idealmente van a patear la promesa hasta el final cuando la capa más profunda termine (me hace pensar en Inception. .. "¡necesitamos ir más profundo!").jQuery diferido - esperando múltiples solicitudes AJAX para terminar

El problema es que estoy enviando muchas solicitudes ajax (posiblemente cientos) a la vez y necesito diferirlas hasta que todas hayan finalizado. No puedo confiar en que el último se haya hecho al último.

function updateAllNotes() { 
    return $.Deferred(function(dfd_uan) { 
     getcount = 0; 
     getreturn = 0; 
     for (i = 0; i <= index.data.length - 1; i++) { 
      getcount++; 
      $.when(getNote(index.data[i].key)).done(function() { 
       // getNote is another deferred 
       getreturn++ 
      }); 
     }; 
     // need help here 
     // when getreturn == getcount, dfd_uan.resolve() 
    }).promise(); 
}; 
+1

http://stackoverflow.com/questions/3709597/wait-until -all-jquery-ajax-request-are-done/9350515 # 9350515 – Benjamin

Respuesta

95

Puede utilizar .when(), y .apply() con diferida múltiple. Extremadamente útil:

function updateAllNotes() { 
    var getarray = [], 
     i, len; 

    for (i = 0, len = data.length; i < len; i += 1) { 
     getarray.push(getNote(data[i].key)); 
    }; 

    $.when.apply($, getarray).done(function() { 
     // do things that need to wait until ALL gets are done 
    }); 
} 
+8

También puede _aceptar_ su propia respuesta. Al hacer esto, puede ayudar a otras personas que enfrentan un problema similar, ya que verán que este problema se ha resuelto en sus resultados de búsqueda. :) – Exa

+0

Gracias. Marcado como aceptado – brittohalloran

+0

¿Hay alguna razón para haber especificado '$' como primer argumento para aplicar? Entiendo que es el contexto de la llamada, pero ¿no es el contexto normal para una llamada de jQuery 'window' o quizás incluso' null'? – Ryley

5

Gracias por la respuesta brittohalloran. También estoy usando subrayados, así que fue capaz de aplicar su solución de forma muy limpia con el mapa, un poco como esto:

$.when.apply($, _.map(data, function(i) { 
    return getNote(i.key); 
})).done(function() { 
    alert('Be Happy'); 
}); 

traviesa útil.

25

Si hace referencia al documento jQuery.When, si una de sus llamadas ajax falla, se llamará a la devolución de llamada fail incluso si todas las siguientes llamadas ajax aún no han finalizado. En este caso, no está seguro de que todas sus llamadas hayan finalizado.

Si desea esperar a que todas sus llamadas, sin importar cuál es el resultado, es necesario utilizar otro diferido como esto:

$.when.apply($, $.map(data, function(i) { 
    var dfd = $.Deferred(); 
    // you can add .done and .fail if you want to keep track of each results individualy 
    getNote(i.key).always(function() { dfd.resolve(); }); 
    return dfd.promise(); 
}); 
+0

No creo que siempre ayude en absoluto, ya que [todavía se ejecuta antes las promesas se cumplen] (http://jsfiddle.net/katowulf/J7H6M/). – Kato

+2

Sí, ayuda si utiliza el mismo código que yo y cumple sus promesas. [He actualizado tu violín] (http://jsfiddle.net/J7H6M/2/) con mi ejemplo, y funciona perfecto. en su enlace, simplemente hizo lo mismo que brittohalloran, dos promesas no incluidas. En este caso, si falla el primero, se invocarán las devoluciones fallidas/siempre, incluso si las próximas promesas no han finalizado. – Mordhak

Cuestiones relacionadas