Mojo::IOLoop::Delay 的顺序请求
Sequentioal requests with Mojo::IOLoop::Delay
我需要在非阻塞模式下获取 URL 列表,但不是并行的。它应该是一个接一个的顺序请求。我怎样才能意识到这一点?
我找不到例子。文档和文章仅突出显示并行执行。
现在我的代码如下所示(简化):
my $delay = Mojo::IOLoop::Delay->new;
$delay->steps(
sub {
build_report();
say "done";
}
);
sub parse_data {
...;
my $url = shift @urls;
my $end = $delay->begin;
$ua->get( $url => \&parse_data );
$end->();
}
my $end = $delay->begin;
$ua->get( $url => \&parse_data );
$end->();
$delay->wait;
我想通过使用 Mojo::IOLoop::Delay
来避免多次关闭。
我刚刚开始考虑 Mojo::IOLoop
自己的项目,但我还不是很熟悉。但我认为最简单的方法是构建一个闭包数组并将其传递给 $delay->steps
.
use strict;
use warnings 'all';
use feature 'say';
use Mojo;
use constant URL => 'http://whosebug.com/questions/tagged/perl';
STDOUT->autoflush;
my $ua = Mojo::UserAgent->new;
my $delay = Mojo::IOLoop::Delay->new;
my @urls = ( URL ) x 10;
my @steps = map {
my $url = $_;
sub {
my $end = $delay->begin;
$ua->get( $url => sub {
my ( $ua, $txn ) = @_;
$end->();
if ( my $err = $txn->error ) {
say $err->message;
}
else {
my $res = $txn->success;
say "@{$res}{qw/ code message /}";
}
});
}
} @urls;
$delay->steps( @steps, sub { say 'Done' } );
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
输出
200 OK
200 OK
200 OK
200 OK
200 OK
200 OK
200 OK
200 OK
200 OK
Done
200 OK
请注意,Done
打印在最终 get
的状态行之前,因为我已立即调用 $end->()
回调到达,假设对响应的任何处理都没有'不需要同步
如果您不想这样,只需将 $end->()
移动到回调的末尾即可。然后延迟将等到输出已生成,然后再发送另一个请求
顺序请求很容易实现。
网络服务器
#!/usr/bin/perl
use Mojo::Base -strict;
use Mojolicious::Lite;
get '/' => sub {
my $c = shift->render_later;
$c->delay(sub {
my $delay = shift;
$c->ua->get('https://google.ru' => $delay->begin);
}, sub {
my ($delay, $tx) = @_;
$tx->res->body; # body of the google.ru
$c->ua->get('https://twitter.com' => $delay->begin);
}, sub {
my ($delay, $tx) = @_;
$tx->res->body; # body of the twitter.com
$c->render(text => 'Done');
});
};
app->start;
脚本
#!/usr/bin/perl
use Mojo::Base -strict;
use Mojo::IOLoop;
use Mojo::UserAgent;
my $ua = Mojo::UserAgent->new;
Mojo::IOLoop->delay(sub {
my $delay = shift;
$ua->get('https://www.google.ru' => $delay->begin);
}, sub {
my ($delay, $tx) = @_;
$tx->res->body; # body of the google.ru
$ua->get('https://twitter.com' => $delay->begin);
}, sub {
my ($delay, $tx) = @_;
$tx->res->body; # body of the twitter.com
warn 'DONE';
})->wait;
脚本(动态请求)
我需要在非阻塞模式下获取 URL 列表,但不是并行的。它应该是一个接一个的顺序请求。我怎样才能意识到这一点?
我找不到例子。文档和文章仅突出显示并行执行。
现在我的代码如下所示(简化):
my $delay = Mojo::IOLoop::Delay->new;
$delay->steps(
sub {
build_report();
say "done";
}
);
sub parse_data {
...;
my $url = shift @urls;
my $end = $delay->begin;
$ua->get( $url => \&parse_data );
$end->();
}
my $end = $delay->begin;
$ua->get( $url => \&parse_data );
$end->();
$delay->wait;
我想通过使用 Mojo::IOLoop::Delay
来避免多次关闭。
我刚刚开始考虑 Mojo::IOLoop
自己的项目,但我还不是很熟悉。但我认为最简单的方法是构建一个闭包数组并将其传递给 $delay->steps
.
use strict;
use warnings 'all';
use feature 'say';
use Mojo;
use constant URL => 'http://whosebug.com/questions/tagged/perl';
STDOUT->autoflush;
my $ua = Mojo::UserAgent->new;
my $delay = Mojo::IOLoop::Delay->new;
my @urls = ( URL ) x 10;
my @steps = map {
my $url = $_;
sub {
my $end = $delay->begin;
$ua->get( $url => sub {
my ( $ua, $txn ) = @_;
$end->();
if ( my $err = $txn->error ) {
say $err->message;
}
else {
my $res = $txn->success;
say "@{$res}{qw/ code message /}";
}
});
}
} @urls;
$delay->steps( @steps, sub { say 'Done' } );
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
输出
200 OK
200 OK
200 OK
200 OK
200 OK
200 OK
200 OK
200 OK
200 OK
Done
200 OK
请注意,Done
打印在最终 get
的状态行之前,因为我已立即调用 $end->()
回调到达,假设对响应的任何处理都没有'不需要同步
如果您不想这样,只需将 $end->()
移动到回调的末尾即可。然后延迟将等到输出已生成,然后再发送另一个请求
顺序请求很容易实现。
网络服务器
#!/usr/bin/perl
use Mojo::Base -strict;
use Mojolicious::Lite;
get '/' => sub {
my $c = shift->render_later;
$c->delay(sub {
my $delay = shift;
$c->ua->get('https://google.ru' => $delay->begin);
}, sub {
my ($delay, $tx) = @_;
$tx->res->body; # body of the google.ru
$c->ua->get('https://twitter.com' => $delay->begin);
}, sub {
my ($delay, $tx) = @_;
$tx->res->body; # body of the twitter.com
$c->render(text => 'Done');
});
};
app->start;
脚本
#!/usr/bin/perl
use Mojo::Base -strict;
use Mojo::IOLoop;
use Mojo::UserAgent;
my $ua = Mojo::UserAgent->new;
Mojo::IOLoop->delay(sub {
my $delay = shift;
$ua->get('https://www.google.ru' => $delay->begin);
}, sub {
my ($delay, $tx) = @_;
$tx->res->body; # body of the google.ru
$ua->get('https://twitter.com' => $delay->begin);
}, sub {
my ($delay, $tx) = @_;
$tx->res->body; # body of the twitter.com
warn 'DONE';
})->wait;
脚本(动态请求)