我需要以非阻塞模式获取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
来避免多次关闭。
答案 0 :(得分:0)
我刚刚开始关注Mojo::IOLoop
一个项目,但我还没有考虑过它。但我认为最简单的方法是构建一个闭包数组并将其传递给$delay->steps
。
use strict;
use warnings 'all';
use feature 'say';
use Mojo;
use constant URL => 'http://stackoverflow.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->()
移至回调的末尾即可。然后延迟将等到产生输出之后再发送另一个请求
答案 1 :(得分:0)
顺序请求非常容易实现。
网络服务器
#!/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;
脚本(动态请求)