Async-Chain
view release on metacpan or search on metacpan
lib/Async/Chain.pm view on Meta::CPAN
package Async::Chain;
use 5.006;
use warnings FATAL => 'all';
use overload ('&{}' => \&_to_code, fallback => 1);
use Carp;
=head1 NAME
Async::Chain - The right way to convert nested callback in plain struct
or just the syntax sugar for guy who do not like deep indent.
=head1 VERSION
Version 0.05
=cut
our $VERSION = '0.05';
=head1 SYNOPSIS
Every subroutine in the chain receive callable object as first argument followed
by arguments of object call. You can break chain in every sub, just do not call
C<$next>.
You can skip some subroutins using C<skip> or C<jump> method.
use Async::Chain;
# with chain call
chain
sub {
my next = shift;
AnyEvent::HTTP::http_get('http://perldoc.perl.org/', $next);
},
sub {
my next = shift;
return $next->jump('log')->(0, "not a 200 response");
...
$db->async_insert(..., cb => $next);
},
sub {
my next = shift;
...
$next->($status, $message);
},
log => sub {
my next = shift;
my ($status, $message) = @_;
...
log(...);
};
=head1 RATIONALE
A asynchronous code often have deep nested callbacks, therefore it is tangled
and hard to change. This module help to converta a code like following to some
more readable form. Also, with C<chain> you can easily skip some unneeded steps
in this thread. For example jump to log step after the first failed query in
the chain.
without chain:
sub f {
...
some_anync_call @args, cb => sub {
...
some_other_anync_call @args, cb => sub {
...
...
...
yet_another_anync_call @args, cb => sub {
...
}
}
}
}
using chain:
chain
sub {
my next = shift;
...
some_anync_call @args, cb => sub { $next->(@arg) }
},
sub {
my next = shift;
...
some_other_anync_call @args, cb => sub { $next->(@arg) }
},
sub {
my next = shift;
...
},
...
sub {
...
yet_another_anync_call @args, cb => sub { $next->(@arg) }
},
sub {
...
};
If you don't need to skip or hitch links, you can use 'kseq' function from CPS
module, that slightly faster.
=head1 SUBROUTINES/METHODS
=cut
# Internal method called by use function
sub import {
$caller = (caller())[0];
*{$caller . "::chain"} = \&chain;
}
( run in 1.074 second using v1.01-cache-2.11-cpan-d8267643d1d )