Skip to content

Commit

Permalink
show flow-control helpers and promises side by side in the cookbook
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Oct 26, 2017
1 parent e56d60b commit 359e455
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
2 changes: 1 addition & 1 deletion lib/Mojo/IOLoop.pm
Expand Up @@ -406,7 +406,7 @@ takes the same arguments as L<Mojo::IOLoop::Client/"connect">.
my $delay = $loop->delay(sub {...});
my $delay = $loop->delay(sub {...}, sub {...});
Build L<Mojo::IOLoop::Delay> object to use as a promise or for flow-control.
Build L<Mojo::IOLoop::Delay> object to use as a promise and/or for flow-control.
Callbacks will be passed along to L<Mojo::IOLoop::Delay/"steps">.
# Wrap continuation-passing style APIs with promises
Expand Down
10 changes: 4 additions & 6 deletions lib/Mojo/IOLoop/Delay.pm
Expand Up @@ -94,8 +94,7 @@ sub then {

sub wait {
my $self = shift;
return if $self->ioloop->is_running;
my $loop = $self->ioloop;
return if (my $loop = $self->ioloop)->is_running;
$self->finally(sub { $loop->stop });
$loop->start;
}
Expand Down Expand Up @@ -157,11 +156,10 @@ sub _wrap {

return sub {
my @result;
unless (eval { @result = $cb->(@_); 1 }) {
$new->reject($@);
}
my $success = eval { @result = $cb->(@_); 1 };
if (!$success) { $new->reject($@) }

elsif (@result == 1 and blessed $result[0] and $result[0]->can('then')) {
elsif (@result == 1 && blessed $result[0] && $result[0]->can('then')) {
$result[0]
->then(sub { $new->resolve(@_); () }, sub { $new->reject(@_); () });
}
Expand Down
26 changes: 25 additions & 1 deletion lib/Mojolicious/Guides/Cookbook.pod
Expand Up @@ -1301,7 +1301,7 @@ synchronize multiple non-blocking requests.
use Mojo::UserAgent;
use Mojo::IOLoop;

# Synchronize non-blocking requests
# Synchronize non-blocking requests with flow-control helpers
my $ua = Mojo::UserAgent->new;
my $delay = Mojo::IOLoop->delay(sub {
my ($delay, $mojo, $minion) = @_;
Expand All @@ -1312,6 +1312,30 @@ synchronize multiple non-blocking requests.
$ua->get('http://metacpan.org/search?q=minion' => $delay->begin);
$delay->wait;

If you plan on doing this a lot it might be worth wrapping your
continuation-passing style APIs into promises, to make them easily composable.

use Mojo::UserAgent;
use Mojo::IOLoop;

# Synchronize non-blocking requests with promises
my $ua = Mojo::UserAgent->new;
sub get {
my $promise = Mojo::IOLoop->delay;
$ua->get(@_ => sub {
my ($ua, $tx) = @_;
$promise->resolve($tx);
});
return $promise;
}
my $mojo = get('http://metacpan.org/search?q=mojo');
my $minion = get('http://metacpan.org/search?q=minion');
$mojo->all($minion)->then(sub {
my ($mojo, $minion) = @_;
say $mojo->result->dom->at('title')->text;
say $minion->result->dom->at('title')->text;
})->wait;

The call to L<Mojo::IOLoop::Delay/"wait"> makes this code portable, it can now
work inside an already running event loop or start one on demand.

Expand Down

0 comments on commit 359e455

Please sign in to comment.