Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jQuery.post动态数据回调函数_Javascript_Jquery_Callback_Http Post - Fatal编程技术网

Javascript jQuery.post动态数据回调函数

Javascript jQuery.post动态数据回调函数,javascript,jquery,callback,http-post,Javascript,Jquery,Callback,Http Post,我有一个脚本,它需要几秒钟的处理时间,最长可达几分钟。该脚本调整图像数组的大小,使其锐化,最后将其拉入拉链供用户下载 现在我需要一些进度消息。 我认为使用jQuery的.post()方法,回调函数中的数据将逐步更新,但这似乎不起作用 在我的示例中,我只是使用一个循环来模拟我的脚本: $(document).ready(function() { $('a.loop').click(function() { $.post('lo

我有一个脚本,它需要几秒钟的处理时间,最长可达几分钟。该脚本调整图像数组的大小,使其锐化,最后将其拉入拉链供用户下载

现在我需要一些进度消息。 我认为使用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";

对于($i=0;$i更新:获取进度信息要容易得多,因为jQuery Ajax请求有一个承诺接口。使用以下答案:


下面的原始答案已经过时(最初是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).'}';
$(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;
  });
});
为了让这一切正常工作,你的图像处理脚本必须留下一些进展的证据

在JavaScript中,类似这样的内容:

/* 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).'}';
$(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

匿名外部函数返回一个内部
函数(数据)
,该函数将是
$.post()的实际回调

我们立即调用外部函数,在此过程中做两件事:使用
setInterval()
触发间隔,并将其返回值(ID)作为参数传入。此参数值将在内部函数调用时(可能在未来几分钟内)可用。
post()的回调
现在可以实际停止间隔

作为你的练习;)

  • 修改ajax调用,使其在请求错误或超时时停止间隔。当前,如果回调从未运行过(并且它只在成功时运行!),那么间隔将永远不会停止
  • 确保不会意外触发两次
    post()

    • 多亏了托马拉克,我终于把一些有用的东西组合起来了。 由于我在处理批处理时并没有在服务器上实际编写图像文件,所以我编写了一个日志文件,我正在progress.php脚本中查阅该文件

      我想知道这是否是最好的方法。我希望避免写入文件,并尝试使用PHP的$\u会话,但似乎无法逐步读取。 美元会话是否可以这样做

      HTML:

      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>";
      

      这是一个严肃的回答,需要一些研究。谢谢托马拉克@FFish:请注意,这些都没有经过实际测试,只是为了让您开始。顺便说一句,我解释得更透彻的是闭包。你会发现很多关于JavaScript闭包的东西,以及它们在互联网上的异步JS编程中的重要性。我坚持你的观点:“为了让它工作,你的图像处理脚本必须留下一些进展的证据。”我尝试使用循环示例中的会话(也尝试使用sleep()来模拟处理),但是脚本会立即执行。为什么我需要2个php脚本?@FFish:你需要一个php来完成转换十几个图像的实际工作。这将在服务器上的线程上运行,直到完成为止,并且在此期间没有响应。您需要一种方法来查询脚本在这段时间内走了多远。要做到这一点,唯一的方法是制作另一个PHP脚本,该脚本将当前进度反馈给您(例如,通过比较完成的图像数量和剩余的图像数量,如图所示)。所以,除非我完全错了,否则两个PHP文件是唯一的方法。。它应该在运行时写入否?它不需要是ajax,请求另一个php页面对我来说很好。干杯
      $filename = "log.txt";
      $handle = fopen($filename, "r");
      $contents = fread($handle, filesize($filename));
      fclose($handle);
      
      echo $contents;