【问题标题】:Do something after rendering in mojolicious在 mojolicious 中渲染后做一些事情
【发布时间】:2020-03-25 13:21:38
【问题描述】:

如何在 HypnoToad 发送页面后让我的代码执行某些操作? (注意:我正在回答我自己的问题。我发布这个问题是因为 StackOverflow 向我指出了一个没有直接解决我的问题的前一个问题,尽管它确实包含了我需要的线索。)

示例代码:

use Mojolicious::Lite;
get "/index" => sub {
   my $c = shift;
   $c->render("renderThis");
   # Do something after rendering
};
app->start('daemon', '-l', 'http://*:8080');

__DATA__
@@ renderThis.html.ep
% layout  "template" ;
<h1>Hello World</h1>

@@ layouts/template.html.ep
<!DOCTYPE html>
<html><head></head><body>
%= content
</body></html>

render 似乎缓冲了它的 http 输出并在代码块完成后发送它。我希望在发送页面后执行某些操作。可以通过将以下内容代替“做某事”注释来观察缓冲。

   sleep 15;
   say "Wow, that was a long time!";

我使用的是 win7,因此仅适用于 unix 的解决方案将无法正常工作。

【问题讨论】:

    标签: perl mojolicious mojolicious-lite


    【解决方案1】:

    您可以将代码附加到finish event on the transaction。大多数其他方法不能保证等到实际发送响应,因为它以异步方式发生。

    use Mojolicious::Lite;
    get "/index" => sub {
       my $c = shift;
       $c->render("renderThis");
       $c->tx->on(finish => sub {
          sleep 15; # this is a really bad idea, use a timer instead
          say "That was a long time, but at least the page got sent quickly.";
       });
    };
    

    【讨论】:

    • 谢谢。这正是我一直在寻找的。我仍然有点喜欢我的 hacky 解决方案,...因为它很 hacky。但是您的答案绝对是正确的方法。我确实发现使用计时器我必须在时隙中输入一个小数字才能使我的实际代码正常工作。我最终使用了 .01 而不是 0。
    【解决方案2】:

    previous question 中的解决方案对我不起作用。 (也就是说,simone 在他的评论中链接到的答案。我没有尝试 mob 提供的分叉解决方案。)我的线索来自 Сухой27 的评论。这是我的解决方案:

    use Mojolicious::Lite;
    use Mojo::IOLoop;
    get "/index" => sub {
       my $c = shift;
       $c->render("renderThis");
       Mojo::IOLoop->timer(0 => sub {
          sleep 15;
          say "That was a long time, but at least the page got sent quickly.";
       });
    };
    app->start('daemon', '-l', 'http://*:8080');
    
    __DATA__
    @@ renderThis.html.ep
    % layout  "template" ;
    <h1>Hello World</h1>
    
    @@ layouts/template.html.ep
    <!DOCTYPE html>
    <html><head></head><body>
    %= content
    </body></html>
    

    计时器将其代码从其调用者的执行流程中取出,因此调用函数在计时器的代码执行之前完成并清除其缓冲区(即使时间参数比调用者完成所需的时间短)。

    注意:我从实验中得到了解释,而不是代码检查,所以我不知道调用者是否在计时器运行其代码之前刷新其所有缓冲区。我所知道的是,在计时器代码运行之前,render 的 http 响应会消失,并且 STDOUT 会被刷新到控制台。我将这些观察结果概括为上述陈述。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多