繁体   English   中英

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

[英]jQuery Ajax / .each callback, next 'each' firing before ajax completed

嗨,当我提交表单时,会调用以下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>");
          }
        });

    });

}

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

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

AJAX是异步的

这正是应该发生的事情。

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

我会给出与jquery json populate表相同的答案

这段代码将为您提供如何使用循环和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);

    }       
}

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM