我有一个朋友想要将数据从一个数据库增量移动到另一个数据库,并在执行此操作时显示错误。我觉得我可以帮他写一个快速的脚本,我在大约一个小时内完成了它,在Opera和Firefox中运行良好(用蜻蜓和萤火虫测试)。当他在Chrome中尝试时,浏览器会锁定,直到for或while循环完成,并且需要相当长的时间才能完成。以下是我的代码(没有读取json的错误捕获部分):
jQuery.noConflict();
jQuery('#myForm').submit(function(form) {
form.preventDefault();
var increment = (jQuery("input#increment").val())*1;
var total = jQuery("input#total").val();
var progress = 0;
jQuery("#progressbar").progressbar({value: 0});
//for (progress = 0; progress < total; progress = progress + increment)
while (progress < total)
{
jQuery.ajax({
url: 'progressBarAjax.php',
type: "POST",
async: false,
dataType: "json",
data: {
ajax: 'goAjax',
total: total,
increment: increment,
progress: progress
},
success: function(data){
jQuery("#progressbar").progressbar({value: data.value});
}
});
progress = progress + increment;
}
});
此外,为了进一步参考,在调试期间删除了捕获错误的代码,data.value=floor(($progress/$total)*100)。你也可以看到我已经尝试了一段时间,在Opera和Firefox中都能很好地工作,但在Chrome中不行。
知道为什么会发生这种行为对于未来的项目来说是件好事,但我也想把它写得正确。目标是进行20万次插入/更新,并将其分解为更小的块,同步运行查询,并在此过程中更新进度条。
好吧,您使用的是async:false
,所以在发出请求时浏览器会锁定。如果增量为0.,则while
也可以进入无限循环
我认为你实际上想查询服务器,如果服务器回来后在json响应中说还没有完成,那么再次查询,直到它说已经完成
var increment, total, progress;
function getProgress(){
jQuery.ajax({
url: 'progressBarAjax.php',
type: "POST",
async: true,
dataType: "json",
data: {
ajax: 'goAjax',
total: total, // Obviously, I don't know what these
increment: increment, // do on your server, so I've kept
progress: progress // them here.
},
success: function(data){
// Assuming data.value is the progress from 1-100?
// otherwise, figure out the progress from the data response
progress = data.value;
jQuery("#progressbar").progressbar({value: progress});
if(progress < 100){
getProgress();
}else{
// All done
alert('done');
}
}
});
}
jQuery('#myForm').submit(function(form) {
form.preventDefault();
// Only go if we aren't currently.
if(progress == null || progress == 100){
increment = (jQuery("input#increment").val())*1;
total = jQuery("input#total").val();
progress = 0;
getProgress();
}
});
如果您正在执行同步AJAX请求,特别是如果您正在按顺序执行多个请求,则浏览器锁定是一种预期行为。
来自jQuery文档:
异步布尔
默认值:真
默认情况下,所有请求都是异步发送的(即,默认情况下设置为true)。如果需要同步请求,请将此选项设置为false。跨域请求和数据类型:"jsonp"请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,从而在请求处于活动状态时禁用任何操作。
文档读起来可能是"may",因为浏览器之间的行为不一致。如果要强制重新绘制页面,则必须允许JavaScript执行周期性终止。为了实现这一点,不使用while循环,而是调用"嵌套的"setTimeout()
s或使用的异步请求,并在上一个请求的回调中调用下一个请求。