我有一个脚本需要几秒钟的处理,最多约一分钟。该脚本调整了一系列图像的大小,锐化它们并最终将它们拉出来供用户下载。
现在我需要某种进度信息。
我在想,使用jQuery的.post()
方法,回调函数中的数据会逐步更新,但这似乎不起作用。
在我的例子中,我只是使用循环来模拟我的脚本:
$(document).ready(function() {
$('a.loop').click(function() {
$.post('loop.php', {foo:"bar"},
function(data) {
$("div").html(data);
});
return false;
});
});
loop.php:
for ($i = 0; $i <= 100; $i++) {
echo $i . "<br />";
}
echo "done";
答案 0 :(得分:5)
更新:由于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()
的回调实际上可以停止间隔。
作为锻炼对你;)
post()
两次。答案 1 :(得分:4)
感谢Tomalak,我终于把一些有用的东西放在了一起。 由于我在处理批处理时实际上并没有在服务器上编写我的图像文件,因此我编写了一个我在progress.php脚本中查询的日志文件。
我想知道这是否是最好的方法。我想避免写入文件并尝试使用PHP的$ _session,但似乎无法逐步读取它。 这可能是$ _session吗?
HTML:
<a class="download" href="#">request download</a>
<p class="message"></p>
JS:
$('a.download').click(function() {
var queryData = {images : ["001.jpg", "002.jpg", "003.jpg"]};
var progressCheck = function() {
$.get("progress.php",
function(data) {
$("p.message").html(data);
}
);
};
$.post('proccess.php', queryData,
function(intvalId) {
return function(data) {
$("p.message").html(data);
clearInterval(intvalId);
}
} (setInterval(progressCheck, 1000))
);
return false;
});
process.php:
$arr = $_POST['images'];
$arr_cnt = count($arr);
$filename = "log.txt";
$i = 1;
foreach ($arr as $val) {
$content = "processing $val ($i/$arr_cnt)";
$handle = fopen($filename, 'w');
fwrite($handle, $content);
fclose($handle);
$i++;
sleep(3); // to mimic image processing
}
echo "<a href='#'>download zip</a>";
progress.php:
$filename = "log.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
echo $contents;