jQuery Ajax / .each回调,在ajax完成之前接下来的'each'触发

时间:2010-12-16 15:48:13

标签: javascript jquery ajax asynchronous each

您提交表单时,会调用以下Javascript。它首先从文本区域中分割出一堆url,然后:

1)为每个网址添加一个表格,在最后一列(“状态”列)中显示“未开始”。
2)再次循环遍历每个URL,首先关闭它进行ajax调用以检查状态(status.php),该状态将返回0 - 100的百分比。 3)在同一个循环中,它通过ajax(process.php)启动实际进程,当进程完成时(记住连续状态更新),它将在状态列中说“已完成”并退出自动刷新。
4)然后它应该转到下一个'each'并为下一个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 个答案:

答案 0 :(得分:13)

你想要的是按顺序运行几个异步动作 ,对吧?我将构建一个函数数组来执行并通过序列帮助程序运行它。

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

btw可以在几行代码中定义音序器功能。例如,

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

答案 1 :(得分:8)

AJAX是异步

这正是应该发生的事情。

您应该在前一个完成处理程序中发送下一个AJAX请求,而不是使用each

答案 2 :(得分:0)

我会给出与jquery json populate table

相同的答案

此代码将为您提供有关如何使用循环和ajax的回调的一些信息。但我没有测试它,会有bug。我从旧代码中导出了以下内容: -

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

    }       
}

答案 3 :(得分:0)

您还可以使用“async”属性将AJAX设置为同步运行。添加以下内容:

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

AJAX API参考here。请注意,这将锁定浏览器,直到请求完成。

我更喜欢SLaks中的方法回答(坚持异步行为)。但是,它取决于您的应用程序。谨慎行事。