Bezdepbonusu7Программирование: статьи и ответы

Вопрос

JQuery Ajax/обратный вызов .each, следующий "каждый" запуск до завершения ajax

Автор вопроса: StuRОтветов: 4

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

1) Добавляет строки в таблицу для каждого URL-адреса, а в последнем столбце (столбце "Статус") написано "Не начато".
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>");
          }
        });

    });

}

javascriptasynchronousjqueryajaxeach

Ответы

Ответ 1 · рейтинг 14 · Michiel Kalkman

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

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

Ответ 2 · рейтинг 8 · SLaks

AJAX является асинхронным.

Это именно то, что должно произойти.

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

Ответ 3 · jthompson

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

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

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

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

Ответ 4 · Sandeepan Nath

Я бы дал тот же ответ, что и этот jquery json populate table

Этот код даст вам небольшое представление о том, как использовать обратный вызов с циклами и 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);

    }
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы