FFi*_*ish 3 javascript jquery callback http-post
我有一个脚本,需要几秒钟的处理,最多约一分钟.该脚本调整图像数组的大小,锐化它们并最终将它们拉链以供用户下载.
现在我需要某种进度信息.我在想,使用jQuery的.post()方法,来自回调函数的数据会逐步更新,但这似乎不起作用.
在我的例子中,我只是使用循环来模拟我的脚本:
$(document).ready(function() {
$('a.loop').click(function() {
$.post('loop.php', {foo:"bar"},
function(data) {
$("div").html(data);
});
return false;
});
});
Run Code Online (Sandbox Code Playgroud)
loop.php:
for ($i = 0; $i <= 100; $i++) {
echo $i . "<br />";
}
echo "done";
Run Code Online (Sandbox Code Playgroud)
更新:获取进度信息要容易得多,因为jQuery Ajax请求具有promise接口.使用这个答案:
以下原始答案已过时(最初来自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).'}';
Run Code Online (Sandbox Code Playgroud)
为此,您的图像处理脚本必须留下一些进展的证据.
在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;
});
});
Run Code Online (Sandbox Code Playgroud)
这部分需要一些解释:
function(intvalId){
return function(data) {
$("div").html(data);
clearInterval(intvalId);
};
}( setInterval(progressCheck, 1000) )
Run Code Online (Sandbox Code Playgroud)
function(intvalId)是一个匿名函数,它接受一个参数 - 一个区间ID.此ID是停止通过设置的间隔所必需的setInterval().幸运的是,调用setInterval()返回这个ID.
匿名外部函数返回一个内部function(data),这个将是实际的回调$.post().
我们立即调用外部函数,在此过程中执行两项操作:触发间隔setInterval()并将其返回值(ID)作为参数传递.内部函数在其调用时可以使用此参数值(可能在将来几分钟内).post()现在的回调实际上可以停止间隔.
作为锻炼对你;)
post()无意中无法触发两次.