2010-09-14 16 views
9

Estoy usando las pestañas jQuery UI, donde cada pestaña tiene una forma diferente. Una vez que el usuario ingresa varios datos, envía todo el conjunto de pestañas para que cada pestaña se publique en el servidor de forma asincrónica. Esto funciona bien, y no tengo problemas aquí.Espere a que finalice la llamada AJAX (POST)

Sin embargo, cuando me encuentro con un problema es que, la última forma que publico tiene que suceder DESPUÉS de que se completen todas las otras publicaciones. idea general es la siguiente:

postForm(0, "#Form1"); 
postForm(1, "#Form2"); 
postForm(2, "#Form3"); 
postForm(3, "#Form4"); 
$.post('Project/SaveProject', function (data) { 
    $('<div class="save-alert">The current project has been saved.</div>') 
    .insertAfter($('#tabs')) 
    .fadeIn('slow') 
    .animate({ opacity: 1.0 }, 3000) 
    .fadeOut('slow', function() { 
     $(this).remove(); 
    }); 
}); 

La función postForm hace un poco de procesamiento y después se hace una llamada AJAX .post $. El último $ .post realizado aquí (a 'Project/SaveProject') debe esperar hasta que se completen esas otras publicaciones. ¿Cuál es la mejor manera de hacerlo?

Respuesta

14

sólo puede utilizar el .ajaxStop() caso de que se activa cuando todos los demás puestos AJAX terminan, asumiendo que usted está haciendo ninguna otra AJAX funciona, entonces, como este:

postForm(0, "#Form1"); 
postForm(1, "#Form2"); 
postForm(2, "#Form3"); 
postForm(3, "#Form4"); 
$(document).ajaxStop(function() { 
    $.post('Project/SaveProject', function (data) { 
    $('<div class="save-alert">The current project has been saved.</div>') 
    .insertAfter($('#tabs')) 
    .fadeIn('slow') 
    .animate({ opacity: 1.0 }, 3000) 
    .fadeOut('slow', function() { 
     $(this).remove(); 
    }); 
    }); 
    $(this).unbind('ajaxStop'); 
}); 

.ajaxStop() incendios cuando todo Solicitudes AJAX que se ejecutan completas, por lo que solo se activará cuando todos de esos POST hayan regresado, jQuery guarde un recuento internamente ($.active, $.ajax.active en jQuery 1.5) para determinar cuántos AJAX simultáneos las misiones son excepcionales ... cuando vuelve a 0, este evento se dispara.

Este enfoque le permite hacer los otros envíos de forma simultánea, y hacer la forma final lo antes posible.

+0

¡Gracias por mencionar '$ .ajax.active' en jQuery 1.5! – Edgar

2

devoluciones de llamada:

Definir postForm tomar una devolución de llamada:

function postForm(ind, id, callback) 
{ 
    // ... 
    $.post(url, function() 
    { 
    // ... 
    callback(); 
    }); 
} 

luego hacer algo como el siguiente. Puede usar la recursividad para escribirla de una manera menos codificada, lo que puede ser particularmente útil si hay más formularios.

postForm(0, "#Form1", function() 
{ 
    postForm(1, "#Form2", function() 
    { 
     postForm(2, "#Form3", function() 
     { 
      postForm(3, "#Form4", function() 
      { 
       $.post('Project/SaveProject', function (data) { 
        $('<div class="save-alert">The current project has been saved.</div>') 
         .insertAfter($('#tabs')) 
         .fadeIn('slow') 
         .animate({ opacity: 1.0 }, 3000) 
         .fadeOut('slow', function() { 
          $(this).remove(); 
         }); 
       }); 
      }); 
     }); 
    }); 
}); 
+0

Gracias por la respuesta. Originalmente había considerado esto, pero luego decidí que era demasiado engorroso trabajar con él. (+1) – JasCav

0

El problema con ajaxStop es que se disparará cada vez que se haga un ajax. Una alternativa está llevando a cabo su propia pila método como este:

var stack = [] 
postForm(var1, var2){ 
    stack.push(1); 
    //Do postForm stuff 
    stack.pop(); 
    if (stack == undefined){ 
     //Call the last post method 
    } 
} 
postForm(0, "#Form1"); 
postForm(1, "#Form2"); 
postForm(2, "#Form3"); 
postForm(3, "#Form4"); 
$.post('Project/SaveProject', function (data) { 
    $('<div class="save-alert">The current project has been saved.</div>') 
    .insertAfter($('#tabs')) 
    .fadeIn('slow') 
    .animate({ opacity: 1.0 }, 3000) 
    .fadeOut('slow', function() { 
     $(this).remove(); 
    }); 
}); 
+0

'ajaxStop()' solo se activará cuando * todas * las solicitudes de AJAX se completen, y lo estoy desvinculando la primera vez que se ejecuta, ¿puede detallar cómo esto podría ser un problema? Además, su ejemplo no funcionará, porque 'stack' será una matriz vacía, no' undefined' :) –

+0

No vio la separación en la parte inferior, discúlpese por eso. Dependiendo de la aplicación, puede haber un montón de llamadas ajax volando alrededor, y en situaciones donde necesitas control absoluto, yo haría mi propia pila de llamadas para mi flujo de trabajo.Por supuesto, su código también funciona (al menos si no hay llamadas ajax anteriormente en la aplicación, donde tendría que definir el controlador en el método postForm) – pederOverland

+0

No estoy vinculando al controlador hasta que este lote de solicitudes sea despedido ya sea :) –

4

Siempre se puede hacer todos los mensajes síncrona usando algo como


$.ajax({ 
    type: "POST",  
    async: false, 
    url: "", 
    ... 

por supuesto que no sería tan rápido pero no soluciona el problema si $ (documento) .ajaxStop no es una opción

+0

Esto realmente no funciona más, devuelve este mensaje: "XMLHttpRequest sincrónico en el hilo principal está en desuso debido a sus efectos perjudiciales para la experiencia del usuario final." – di3sel

Cuestiones relacionadas