Mojoliciousでdeferred使う
非同期APIを2つ読んで、その2つが処理結果をもって、次の処理をしたいって ことあると思います。 普通にかくとネストが深くなってしまったりします。
DB2の勉強会でjqueryのDefferdを知り http://db2.jugem.cc/?month=201207
Perlでもあるんだろうなぁーと、うすうす感じていたら、ありました。 Promisesというんですね。 http://d.hatena.ne.jp/debug-ito/20121123
さて、Mojoliciousから使うサンプルみたいなものをつくってみました。 非常にすっきり書けます。
#!/usr/bin/env perl use Mojolicious::Lite; use Promises backend => ['Mojo'], qw[ deferred collect ]; get '/' => sub { my $self = shift; my $d1 = deferred; Mojo::IOLoop->timer(10 => sub { $d1->resolve("boo"); }); my $d2 = deferred; Mojo::IOLoop->timer(3 => sub { $d2->resolve("foo"); }); collect( $d1->promise(), $d2->promise() )->then( sub { my ($result1, $result2) = @_; $self->render("index",result => @$result1[0] . @$result2[0]); }, sub { # error } ); }; app->start; __DATA__ @@ index.html.ep % layout 'default'; % title 'Welcome'; Result:<%= $result %> @@ layouts/default.html.ep <!DOCTYPE html> <html> <head><title><%= title %></title></head> <body><%= content %></body> </html>