JavaScript для цикла с innerHTML не обновляется во время выполнения цикла - PullRequest
0 голосов
/ 30 октября 2011

Я перебираю массив, и во время каждой итерации цикла я вызываю URL через ajax.Я также хотел бы обновить .innerHTML таким образом, чтобы он отображал информацию, информирующую пользователя о том, какая итерация цикла обрабатывается.Однако .innerHTML отображает обновление только после завершения сценария.

Как сделать так, чтобы это уведомление отображалось во время цикла?

Я также использую параметр ajax запроса 'async: false'.Я не хочу, чтобы мой сервер обрабатывал все запросы ajax одновременно, поскольку они кодируют видеофайлы, которые интенсивно загружают процессор.На самом деле я не хочу блокировать браузер, ожидающий завершения синхронных запросов.

Есть ли лучший способ сделать это?

Моя конечная цель - последовательно выполнить мой комбайн.PHP-скрипт для каждого набора видео, отображая текущий индикатор состояния для пользователя и не блокируя браузер в процессе.Ваша помощь приветствуется!

Фрагмент кода здесь:

</p> <pre><code>// process the loop of videos to be combined var status = document.getElementById('currentStatus'); for (i=0; i< count; i++) { // change the display var fields = videos[i].split(":", 2); current = i +1; currentStatus.innerHTML = "<b>Multi-part Videos:</b>&nbsp;&nbsp;&nbsp; <h3 class='status'>Currently Updating Bout #" + fields[1] + " (" + current + " of " + count + " videos)</h3>"; // run the combine var dataString = 'videoId='+ fields[0]; $.ajax({ type: "POST", url: "combine.php", data: dataString, success: function(txt) { //deselect the checkbox document.combine.video[selected[i]].checked = false; }, async: false });

Ответы [ 3 ]

1 голос
/ 30 октября 2011

Как уже упоминали другие, ваша проблема вызвана тем, что JavaScript является однопоточным - пока один поток JS ожидает возврата вашего ajax-запроса, обновление пользовательского интерфейса не разрешено.

Вы можете обойтиэто путем изменения запроса на асинхронный и использования обратного вызова для запуска запроса на следующий объект:

// trigger the loop of videos to be combined
var status = document.getElementById('currentStatus');
processVideo( 0 );

function processVideo( index ) {
    var fields = videos[index].split(":", 2);

    currentStatus.innerHTML = "<b>Multi-part Videos:</b>&nbsp;&nbsp;&nbsp; <h3 class='status'>Currently Updating Bout #" + fields[1] + " (" + current + " of " + count + " videos)</h3>";

    // run the combine 
    var dataString = 'videoId='+ fields[0]; 

    $.ajax({  
        type: "POST",  
        url: "combine.php",  
        data: dataString,  
        success: function() {
           processResponse( index);
        },
        async: true
    });
}

function processResponse( index ) {
   // this method is called each time the ajax request finishes
   if (index++ < count) {
      //deselect the checkbox
      document.combine.video[selected[index]].checked = false;

      processVideo( index );
   }
}
1 голос
/ 30 октября 2011

async: false будет зависать весь браузер, пока не завершится запрос ajax.Вот почему вы не видите обновления страницы на каждой итерации цикла.

Синхронные запросы ajax обычно приводят к ужасному UX (вам вам нравится, что страница неожиданно зависает?)почти всегда лучший способ сделать это.Поскольку вы используете jQuery, API отложенных объектов делает это простым.

0 голосов
/ 30 октября 2011

Если вы хотите обновить одно за другим, когда async установлен в true, следующий запрос может быть помещен в функцию обратного вызова success.Код состояния обновления также должен быть внутри этой функции.

function ajaxRequest(i){

        // other processing
        .............

        $.ajax({  
            type: "POST",  
            url: "combine.php",  
            data: dataString,  
            success: function(txt) {

                //deselect the checkbox
                document.combine.video[selected[i]].checked = false;

                // update status
                currentStatus.innerHTML = .....
                // make next request
                if(i<lastOne){
                     ajaxRequest(i+1);
                }
            },
            async: true
        }); 
}
...