2

我为使用客户端 PerlScript 的 IE 编写了一个非常小的 html 页面。在脚本中,我启动了一个创建 TCP 套接字的单独进程。启动该过程后,我启动了一个侦听器,它在读取行时将 HTML 附加到 div 的末尾,另外为了调试,我在读取每一行时添加了警报。

问题是警报会在读取行时出现,但 HTML 不会更新,直到该过程完成。这是为什么?有没有办法强制页面呈现,以便我可以获得相同的行为?

这是页面:

<html>
    <head>
        <title>Message Test</title>
        <script language=perlscript>
            use util;
            use Win32::Process;

            my $alreadyrunflag = 0;

            sub _write {
                $window->document->body->insertAdjacentHTML("beforeEnd", $_[0]);
            }

            sub go {
                _write("starting!<br/>");

                my $port = 12345;
                #//system("start /b /NORMAL perl C:/development/plslog/clitest2.pl $port");
                Win32::Process::Create(my $Proc, "C:/perl/bin/perl.exe", "perl clitest2.pl 12345", 1, CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS | DETACHED_PROCESS, "C:/development/plslog");
                $window->alert("Hi! started!");

                if (defined (my $INPUT = util::CreateClient($port))) {
                    while(defined (my $line = <$INPUT>)) {
                       _write($line);
                        sleep(3);
                    }
               }

               _write("ending!");
            }

            $window->setTimeout("go()",0);
        </script>
    </head>
    <body>
        <div id="content"></div>
    </body>
</html>

我查看了 PerlScript 的在线文档,该文档非常稀疏。我正在寻找有关如何命令 IE 触发页面呈现、响应这些 html 插入...等的提示。

在研究这一点时,我发现如果我在 div 上使用 onclick 而不是 onload,我可以在读取行时渲染它。也许我没有使用正确的事件并且在触发子例程之前页面没有完全呈现?我对这里的 IE 感到非常沮丧(第 9 节)。

是的,当我在命令行情况下使用它时,一切都会按预期触发。CreateServer/CreateClient 只是客户端和服务器的 IO::Socket::INET 的包装器。

更新(基于@Oleg V. Volkov 的回答):

我修改了 go 并添加了一个读取一行的 _read() 函数,然后将控制权传递回浏览器进行渲染。似乎做得不错。

sub _read() {
  my $port = shift;
  $INPUT = util::CreateClient($port) if ! $INPUT;
  if (defined (my $line = <$INPUT>)) {
    _write($line);
    $window->setTimeout("_read($port)", 0);
  }
  else {
    _write("Fin!");
  }
}
sub go() {
  _write("starting!<br/>");
  my $port = 12345;
  Win32::Process::Create(my $Proc, "C:/perl/bin/perl.exe", "perl clitest2.pl $port", 1, CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS | DETACHED_PROCESS, "C:/development/plslog");
  $window->alert("Hi! started!");
  $window->setTimeout("_read($port)", 0);
}

这似乎接近实时更新。

4

1 回答 1

2

大多数(如果不是全部)浏览器在您从托管脚本进程返回之前不会重绘页面。他们可以在某些操作上重排数据的内部表示,但在您返回控制权之前仍然不会花时间重绘它。setTimeout为了允许浏览器重绘,你应该将你的任务分成几个步骤,并return通过在脚本中安排下一步并偶尔让步。

在您的特定情况下,替换sleep(3),无论如何您什么都不做,安排下一次循环迭代在 3 秒后发生,似乎是最好的方法。

于 2012-05-25T17:22:17.567 回答