AnyEvent-Promises
view release on metacpan or search on metacpan
lib/AnyEvent/Promises.pm view on Meta::CPAN
sub make_promise {
my $arg = shift;
return $arg if is_promise($arg);
my $d = deferred();
if ( ref $arg && ref $arg eq 'CODE' ) {
$d->resolve;
return $d->promise->then($arg);
}
else {
$d->resolve($arg);
return $d->promise;
}
}
sub merge_promises {
my @promises = @_;
my $d = deferred();
my $left = @promises;
my @result;
for my $i ( 0 .. $#promises ) {
$promises[$i]->then(
sub {
# only the first value is taken into consideration
$result[$i] = $_[0];
--$left or $d->resolve(@result);
},
sub {
$d->reject(@_);
}
);
}
if (!$left){
# is true only when @promises is empty
$d->resolve;
}
return $d->promise;
}
# actually is_thenable
sub is_promise {
my ($cand) = @_;
return blessed($cand) && $cand->can('then');
}
sub settle_promises {
my @promises = shift;
my $d = deferred();
my $left = @promises;
my $cb = sub { --$left or $d->resolve(@promises); };
$_->then( $cb, $cb ) for @promises;
return $d->promise;
}
1;
# vim: expandtab:shiftwidth=4:tabstop=4:softtabstop=0:textwidth=78:
__END__
=pod
=head1 NAME
AnyEvent::Promises - simple implementation of Promises/A+ spec
=head1 VERSION
version 0.06
=head1 SYNOPSIS
use AnyEvent::Promises qw(deferred merge_promises);
use AnyEvent::HTTP;
use JSON qw(decode_json encode_json);
sub wget {
my ($uri) = @_;
my $d = deferred;
http_get $uri => sub {
my ( $body, $headers ) = @_;
$headers->{Status} == 200
? $d->resolve( decode_json($body) )
: $d->reject('receiving data failed with status: '. $headers->{Status} );
};
return $d->promise;
}
sub wput {
my ($uri, $data) = @_;
my $d = deferred;
http_put $uri, body => encode_json($data) => sub {
my ( $body, $headers ) = @_;
$headers->{Status} == 200 || $headers->{Status} == 204
? $d->resolve( $body? decode_json($body) )
: $d->reject('putting data failed with status: '. $headers->{Status} );
};
return $d->promise;
}
my $cv = AnyEvent->condvar;
merge_promises(
wget('http://rest.api.example.com/customer/12345'),
wget('http://rest.api.example.com/order/2345'),
wget('http://rest.api.example.com/payment/3456')
)->then(
sub {
my ($customer, $order, $payment) = @_;
my $data = mix_together($customer, $order, $payment);
return wput('http://rest2.api.example.com/aggregate/567', $data);
}
)->then(
sub {
# do something after the data are send
},
( run in 1.372 second using v1.01-cache-2.11-cpan-97f6503c9c8 )