Mojo::IOLoop::Delay - Promises/A+とフローコントロールヘルパーのイベントの同期
使い方
use Mojo::IOLoop::Delay;
# 複数のノンブロックオペレーションの同期
my $delay = Mojo::IOLoop::Delay->new;
$delay->steps(sub { say 'BOOM!' });
for my $i (1 .. 10) {
my $end = $delay->begin;
Mojo::IOLoop->timer($i => sub {
say 10 - $i;
$end->();
});
}
$delay->wait;
# 複数のノンブロッキングオペレーションの直列化
Mojo::IOLoop::Delay->new->steps(
# 最初のステップ(タイマーに似ている)
sub {
my $delay = shift;
Mojo::IOLoop->timer(2 => $delay->begin);
say 'Second step in 2 seconds.';
},
# 次のステップ (連続したタイマー)
sub {
my ($delay, @args) = @_;
Mojo::IOLoop->timer(1 => $delay->begin);
Mojo::IOLoop->timer(3 => $delay->begin);
say 'Third step in 3 seconds.';
},
# 三回目のステップ (最後)
sub {
my ($delay, @args) = @_;
say 'And done after 5 seconds total.';
}
)->wait;
説明
Mojo::IOLoop::Delayは、フローコントロールヘルパーをMojo::Promiseに追加します。 連続渡しスタイルで深くネストされたクロージャーを避けるのを助けます。
use Mojo::IOLoop;
# これらの深いネストのクロージャーは、コールバックヘルとして言及されています。
Mojo::IOLoop->timer(3 => sub {
my loop = shift;
say '3 seconds';
Mojo::IOLoop->timer(3 => sub {
my $loop = shift;
say '6 seconds';
Mojo::IOLoop->timer(3 => sub {
my $loop = shift;
say '9 seconds';
Mojo::IOLoop->stop;
});
});
});
Mojo::IOLoop->start;
属性
Mojo::IOLoop::Delayは Mojo::Promiseからすべての属性を継承しています。
メソッド
Mojo::IOLoop::DelayはMojo::EventEmitterからすべてのメソッドを継承しており、 次の新しいメソッドを実装しています。
begin
my $cb = $delay->begin; my $cb = $delay->begin($offset); my $cb = $delay->begin($offset, $len);
アクティブなイベントのカウンターをインクリメント することによって、アクティブなイベントを指示します。
返却されるコールバックは、 イベントが完了するときに、呼び出される必要があります。 このとき、アクティブなイベントのカウントを、再びデクリメントします。
すべてのコールバックが呼び出され、アクティブイベントカウンタ がゼロに到達したtき、stepsが続きます。
# 最初のものを除いてすべての引数をキャプチャ(呼び出し)
my $delay = Mojo::IOLoop->delay(sub {
my ($delay, $err, $stream) = @_;
...
});
Mojo::IOLoop->client({port => 3000} => $delay->begin);
$delay->wait;
返却されるコールバックに渡された引数は、与えられたオフセットと長さで、 分割されます。デフォルトのオフセットは1で長さは持ちません。 引数はbeginが呼び出されるのと同じ順序で、結び付けられ、 次のステップかfinishイベントへ一緒に渡されます。
# すべての引数をキャプチャ
my $delay = Mojo::IOLoop->delay(sub {
my ($delay, $loop, $err, $stream) = @_;
...
});
Mojo::IOLoop->client({port => 3000} => $delay->begin(0));
$delay->wait;
# 二つ目の引数だけをキャプチャ
my $delay = Mojo::IOLoop->delay(sub {
my ($delay, $err) = @_;
...
});
Mojo::IOLoop->client({port => 3000} => $delay->begin(1, 1));
$delay->wait;
# キャプチャして、引数を結合する
my $delay = Mojo::IOLoop->delay(sub {
my ($delay, $three_err, $three_stream, $four_err, $four_stream) = @_;
...
});
Mojo::IOLoop->client({port => 3000} => $delay->begin);
Mojo::IOLoop->client({port => 4000} => $delay->begin);
$delay->wait;
pass
$delay = $delay->pass; $delay = $delay->pass(@args);
アクティブなイベントカウンタをインクリメントし、次のステップへ値を渡すために、すぐに値をデクリメントします。
# 長いバージョン $delay->begin(0)->(@args);
steps
$delay = $delay->steps(sub {...}, sub {...});
複数のイベントをシーケンシャルに扱います。 最初のコールバックはすぐに実行されます。 次のコールバックは、イベントのカウンターが0に到達したときに実行されます。 このチェーンは、コールバックがなくなるか、 アクティブイベントカウンターがインクリメントできなくなるまで続きます。
参考
Mojolicious, Mojolicious::Guides, http://mojolicio.us.
(Mojolicious 8.12を反映。2019年5月22日更新)
Mojoliciousドキュメント日本語訳