更新:获取进度信息,因为jQuery的阿贾克斯容易得多请求有一个承诺接口。使用这样的回答:
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()
不会无意中被触发两次。
这是一个认真的答复,需要一些研究。感谢Tomalak! – FFish 2010-04-12 19:54:04
@FFISH:请注意,这些都没有经过实际测试,它只是让你开始。我更彻底地解释的东西被称为封闭,顺便说一句。你会发现很多关于JavaScript闭包的东西,以及它们在互联网上异步JS编程中的重要性。 – Tomalak 2010-04-12 20:30:44
我被你的线卡住了“为了这个工作,你的图像处理脚本必须留下一些当然的进展证据。” 我尝试了与循环示例的会话(也尝试用sleep()来模拟处理),但脚本立即执行。为什么我需要2个PHP脚本? – FFish 2010-04-12 22:52:19