Обновление: Получение информации о ходе выполнения намного проще, так как запросы jQuery Ajax имеют интерфейс обещаний. Используйте этот ответ:
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)
- анонимная функция, которая принимает один аргумент - идентификатор интервала. Этот идентификатор необходим для остановки интервала, установленного с помощью setInterval()
. К счастью, звонок на setInterval()
возвращает именно этот идентификатор.
Анонимная внешняя функция возвращает внутреннюю function(data)
, эта будет реальным обратным вызовом для $.post()
.
Мы немедленно вызываем внешнюю функцию, выполняя в процессе две вещи: запуск интервала с setInterval()
и передачу его возвращаемого значения (ID) в качестве аргумента. Это значение аргумента будет доступно внутренней функции во время ее вызова (что может занять несколько минут в будущем). Обратный вызов для post()
теперь может фактически остановить интервал.
Как упражнение для вас;)
- Измените вызов ajax так, чтобы он также останавливал интервал при ошибке запроса или тайм-ауте. В настоящее время, если обратный вызов никогда не запускается (и выполняется только в случае успеха!), Интервал никогда не остановится.
- Убедитесь, что
post()
не может быть случайно запущен дважды.