[英]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.