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日更新)