jQuery Ajax / .each回调,在ajax完成之前下一个’each’触发

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

1)为每个url添加一个表格,在最后一列(“状态”列)中显示“未开始”。
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(''+value+'Not Started'); }); $.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(""+data+""); } }); }, 1000); $.ajax({ url: 'process.php?id='+value, success: function(msg) { clearInterval(auto_refresh); $('#dlTable').find("tr").eq(key+1).children().last().replaceWith("completed rip"); } }); }); } 

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

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。 例如,

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

AJAX是异步的

这正是应该发生的事情。

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

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

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

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

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

我会给出与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(''+value+'Not Started'); }); completeProcessing(lines ,function(success) { $.ajax({ url: 'process.php?id='+value, success: function(msg) { $('#dlTable').find("tr").eq(key+1).children().last().replaceWith("completed rip"); } }); }); } //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(""+data+""); processCnt++; callback(false); } }); } else { callback(true); } }