Обратный вызов jQuery Ajax / .each, следующий «каждый» запуск до завершения ajax - PullRequest
5 голосов
/ 16 декабря 2010

Привет ниже Javascript вызывается, когда я отправляю форму. Сначала он разбивает несколько URL-адресов из текстовой области, а затем:

1) Добавляет строки в таблицу для каждого URL-адреса, а в последнем столбце (столбец «статус») отображается «Not Started».
2) Опять же, он перебирает каждый URL, сначала он делает ajax-вызов для проверки статуса (status.php), который возвращает процент от 0 до 100.
3) В том же цикле он запускает реальный процесс через ajax (process.php), когда процесс завершается (учитывая постоянные обновления статуса), он затем говорит «Завершено» в столбце состояния и выходит auto_refresh.
4) Затем следует перейти к следующему «каждому» и сделать то же самое для следующего 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>");
          }
        });

    });

}

Ответы [ 4 ]

13 голосов
/ 16 декабря 2010

То, что вы хотите - это выполнить несколько асинхронных действий в последовательности , верно? Я бы собрал массив функций для выполнения и запустил его через хелпер последовательности.

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();
          }
        });
    });
  }
);

Как видите, мы строим массив функций с областями видимости, которые принимают произвольный обратный вызов в качестве аргумента. Секвенсор запустит их для вас.

Используйте хелпер последовательности из ссылки на github и запустите,

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

Между прочим, можно определить функции секвенсора в нескольких строках кода. Например,

function sequencer(arr) {
    (function() {
        ((arr.length != 0) && (arr.shift()(arguments.callee)));
    })();
}
8 голосов
/ 16 декабря 2010

AJAX асинхронный .

Именно так и должно быть.

Вместо использования each вы должны отправить следующий запрос AJAX в обработчик завершения предыдущего.

0 голосов
/ 16 декабря 2010

Вы также можете настроить синхронную работу AJAX, используя свойство «async». Добавить следующее:

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

Справочник по AJAX API здесь . Обратите внимание, что это заблокирует браузер, пока запрос не будет завершен.

Я предпочитаю подход в ответе SLaks (придерживаясь асинхронного поведения). Тем не менее, это зависит от вашего приложения. Соблюдайте осторожность.

0 голосов
/ 16 декабря 2010

Я бы дал тот же ответ, что и jquery json Заполнить таблицу

Этот код даст вам небольшое представление о том, как использовать обратный вызов с циклами и ajax.Но я не проверял это, и будут ошибки.Из моего старого кода я получил следующее: -

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);

    }       
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...