在 mojolicious 中渲染后做一些事情
Do something after rendering in mojolicious
如何让我的代码在 HypnoToad 发送页面后执行某些操作? (注意:我是在回答我自己的问题。我发布这个是因为 Whosebug 向我指出了一个没有直接解决我的问题的问题,尽管它确实包含了我需要的线索。)
示例代码:
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 输出并在代码块完成后发送它。我想在页面发送后执行一些操作。可以通过将以下内容替换 "Do something" 注释来观察缓冲。
sleep 15;
say "Wow, that was a long time!";
我在 win7 上,所以仅 unix 的解决方案不起作用。
中的解决方案对我不起作用。 (也就是说,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 被刷新到控制台。我概括了这些观察结果以做出上述陈述。
您可以将代码附加到 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.";
});
};
如何让我的代码在 HypnoToad 发送页面后执行某些操作? (注意:我是在回答我自己的问题。我发布这个是因为 Whosebug 向我指出了一个没有直接解决我的问题的问题,尽管它确实包含了我需要的线索。)
示例代码:
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 输出并在代码块完成后发送它。我想在页面发送后执行一些操作。可以通过将以下内容替换 "Do something" 注释来观察缓冲。
sleep 15;
say "Wow, that was a long time!";
我在 win7 上,所以仅 unix 的解决方案不起作用。
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 被刷新到控制台。我概括了这些观察结果以做出上述陈述。
您可以将代码附加到 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.";
});
};