鈍足ランナーのIT日記

走るのが好きな5流のITエンジニアのブログ。

趣味の範囲は広いけど、どれも中途半端なクソブロガー楽しめるWebアプリを作ってあっと言わせたい。サーバーサイドPerl(Mojolicious)、クライアントサイドVue.js。Arduinoにも触手を伸ばす予定。

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>