更新:由于 jQuery Ajax 请求有一个 Promise 接口,因此获取进度信息要容易得多。使用这个答案:
https://stackoverflow.com/a/32272660/18771
下面的原始答案已过时(最初来自 2010 年)。它仍然有效,但比它需要的更复杂。我会保留它以供参考和比较。
您需要来自服务器的某种进度信息。ajax 回调不进行渐进式工作,它们只触发一次 - 在请求成功返回之后。
所以......在PHP中你需要这样的东西:
/* progress.php */
$batch_done = some_way_to_find_out_that_number();
$batch_size = some_way_to_find_out_that_number_too();
header('Content-type: application/json');
// TODO: format number
echo '{"progress":'. ($batch_size==0 ? '0' : $batch_done*100.0/$batch_size).'}';
为此,您的图像处理脚本当然必须留下一些其进展的证据。
在 JavaScript 中是这样的:
$(document).ready(function() {
$('a.loop').click(function() {
var queryData = {foo:"bar"};
// prepare a function that does cyclic progress checking
var progressCheck = function() {
$.getJSON(
"progress.php", queryData,
function(data) {
$("div.progress").css("width", data.progress+"%");
}
)
};
$.post(
'loop.php', queryData,
/* create the post request callback now */
function(intvalId){
return function(data) {
$("div").html(data);
clearInterval(intvalId);
}
}( setInterval(progressCheck, 1000) )
);
return false;
});
});
这部分需要一些解释:
function(intvalId){
return function(data) {
$("div").html(data);
clearInterval(intvalId);
};
}( setInterval(progressCheck, 1000) )
function(intvalId)
是一个匿名函数,它接受一个参数 - 一个区间 ID。此 ID 是停止已通过 设置的间隔所必需的setInterval()
。幸运的是,调用setInterval()
返回这个 ID。
匿名外部函数返回一个内部function(data)
,这将是$.post()
.
我们立即调用外部函数,在此过程中做两件事:触发间隔setInterval()
并将其返回值(ID)作为参数传递。该参数值将在内部函数调用时(可能在未来几分钟内)可用。现在的回调post()
实际上可以停止间隔。
作为你的练习;)
- 修改 ajax 调用,使其也停止请求错误或超时的间隔。目前,如果回调从未运行(并且仅在成功时运行!),则间隔将永远不会停止。
- 确保
post()
不会意外触发两次。