2010-12-16 8 views
5

Hola el siguiente se llama Javascript cuando envío un formulario. Primero divide un montón de url de un área de texto, luego:jQuery Ajax/.each devolución de llamada, el siguiente 'cada' disparo antes de ajax completado

1) Agrega líneas a una tabla para cada url, y en la última columna (la columna 'estado') dice "No iniciado".
2) Nuevamente pasa por cada url, primero realiza una llamada ajax para verificar el estado (status.php) que devolverá un porcentaje de 0 - 100.
3) En el mismo ciclo, se inicia el proceso real a través de ajax (process.php), cuando el proceso se haya completado (teniendo en cuenta las actualizaciones de estado continuas), dirá "Completado" en la columna de estado y saldrá de la actualización automática.
4) Debería pasar al siguiente 'cada' y hacer lo mismo para la siguiente url.

function formSubmit(){ 

    var lines = $('#urls').val().split('\n'); 

    $.each(lines, function(key, value) { 
     $('#dlTable tr:last').after('<tr><td>'+value+'</td><td>Not Started</td></tr>'); 
    }); 

    $.each(lines, function(key, value) { 

     var auto_refresh = setInterval(function() { 
      $.ajax({ 
       url: 'status.php', 
       success: function(data) { 
      $('#dlTable').find("tr").eq(key+1).children().last().replaceWith("<td>"+data+"</td>"); 
       } 
      }); 
     }, 1000); 

     $.ajax({ 
      url: 'process.php?id='+value, 
      success: function(msg) { 
     clearInterval(auto_refresh); 
     $('#dlTable').find("tr").eq(key+1).children().last().replaceWith("<td>completed rip</td>"); 
      } 
     }); 

    }); 

} 

Respuesta

12

Lo que quiere es ejecutar varias acciones asincrónicas en secuencia, ¿verdad? Construiría un conjunto de funciones para ejecutarlo y ejecutarlo a través de un asistente de secuencia.

https://github.com/michiel/asynchelper-js/blob/master/lib/sequencer.js

var actions = []; 
$.each(lines, function(key, value) { 

    actions.push(function(callback) { 
     $.ajax({ 
      url: 'process.php?id='+val, 
      success: function(msg) { 
      clearInterval(auto_refresh); 

      // 
      // Perform your DOM operations here and be sure to call the 
      // callback! 
      // 

      callback(); 
      } 
     }); 
    }); 
    } 
); 

Como se puede ver, construimos una serie de funciones de ámbito que tienen una devolución de llamada arbitraria como argumento. Un secuenciador los ejecutará en orden para usted.

los auxiliares de secuencia desde el enlace de GitHub y correr,

var sequencer = new Sequencer(actions); 
sequencer.start(); 

Es, por cierto, es posible definir funciones de secuenciador en unas pocas líneas de código. Por ejemplo,

function sequencer(arr) { 
    (function() { 
     ((arr.length != 0) && (arr.shift()(arguments.callee))); 
    })(); 
} 
+1

Perfecto, justo lo que buscaba. Gracias. – StuR

7

AJAX es asíncrona.

Eso es exactamente lo que se supone que debe suceder.

En lugar de usar each, debe enviar la siguiente solicitud de AJAX en el controlador de finalización del anterior.

0

le daría la misma respuesta que esta jquery json populate table

Este código le dará un poco de idea de cómo utilizar de respuesta con bucles y Ajax. Pero no lo he probado y habrá errores. Derivé lo siguiente de mi viejo código: -

var processCnt; //Global variable - check if this is needed 
function formSubmit(){ 

    var lines = $('#urls').val().split('\n'); 

    $.each(lines, function(key, value) { 
     $('#dlTable tr:last').after('<tr><td>'+value+'</td><td>Not Started</td></tr>'); 
    }); 

    completeProcessing(lines ,function(success) 
    { 
      $.ajax({ 
      url: 'process.php?id='+value, 
      success: function(msg) { 
       $('#dlTable').find("tr").eq(key+1).children().last().replaceWith("<td>completed rip</td>"); 
      } 
     }); 


    }); 


} 

//Following two functions added by me 
function completeProcessing(lines,callback) 
{ 
    processCnt= 0; 
    processingTimer = setInterval(function() { singleProcessing(lines[processCnt],function(completeProcessingSuccess){ if(completeProcessingSuccess){ clearInterval(processingTimer); callback(true); }})}, 1000);  

} 


function singleProcessing(line,callback) 
{ 
    key=processCnt; 
    val = line; 
    if(processCnt < totalFiles) 
    { //Files to be processed 

     $.ajax({ 
        url: 'status.php', 
        success: function(data) { 
          $('#dlTable').find("tr").eq(key+1).children().last().replaceWith("<td>"+data+"</td>"); 
         processCnt++; 
         callback(false); 

        } 
       }); 
    } 
    else 
    { 
     callback(true); 

    }  
} 
0

También puede establecer AJAX para ejecutar de forma sincrónica utilizando la propiedad "asíncrono". Agregue el siguiente:

$.ajax({ "async": false, ... other options ... }); 

AJAX referencia de la API here. Tenga en cuenta que esto bloqueará el navegador hasta que la solicitud se complete.

Prefiero el enfoque en la respuesta de SLaks (siguiendo el comportamiento asincrónico). Sin embargo, depende de tu aplicación. Ten cuidado.

+0

No haga esto. Congelará completamente el navegador hasta que el servidor responda. – SLaks

+0

Se completó la respuesta porque la opción está disponible. Seguir con las llamadas asincrónicas es mejor. – jthompson

+0

+1 para completar –

Cuestiones relacionadas