在循环执行期间没有更新innerHTML的JavaScript for循环

时间:2011-10-30 16:18:28

标签: javascript ajax loops innerhtml

我循环遍历数组,在循环的每次迭代中,我通过ajax调用url。我还想更新一个.innerHTML,使其显示以使用户知道正在处理循环的哪个迭代。但是,.innerHTML仅在脚本完成时显示更新。

如何在循环中显示此通知?

我也在使用查询ajax设置'async:false'。我不想一次处理所有ajax请求,因为他们正在编码CPU密集型的视频文件。我真的不想锁定浏览器等待同步请求完成。

有更好的方法吗?

我的最终目标是为每组视频顺序执行我的combine.php脚本,同时向用户显示当前状态指示器,同时不在此过程中锁定浏览器。感谢您的帮助!

此处的代码段:

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

// 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 个答案:

答案 0 :(得分:1)

async: false将挂起整个浏览器,直到ajax请求完成。这就是为什么你没有看到每次循环迭代的页面更新。

同步ajax请求通常会导致可怕的用户体验(像页面一样莫名其妙地冻结?)并且几乎总有一种更好的方法可以做到这一点。由于你正在使用jQuery,Deferred Object API使这很容易。

答案 1 :(得分:1)

正如其他人所提到的,你的问题是因为JavaScript是单线程的 - 而单个JS线程正在等待你的ajax请求返回,所以不允许更新UI。

您可以通过将请求更改为异步来解决此问题,并使用回调来触发对下一个对象的请求:

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

答案 2 :(得分:0)

如果要在async设置为true时逐个更新,则可以将下一个请求放入成功回调函数中。更新状态代码也应该在该函数内部。

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