Navigation Menu

Skip to content

Commit

Permalink
steps now settle the promise and wait is based on finally
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Oct 24, 2017
1 parent 8de82b9 commit 96a5717
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 6 deletions.
43 changes: 37 additions & 6 deletions lib/Mojo/IOLoop/Delay.pm
Expand Up @@ -39,6 +39,29 @@ sub catch { shift->then(undef, shift) }

sub data { Mojo::Util::_stash(data => @_) }

sub finally {
my ($self, $finally) = @_;

my $new = $self->_clone;
my $cb = sub {
my ($method, @result) = @_;
my ($promise) = eval { $finally->(@result) };
if ($promise && blessed $promise && $promise->can('then')) {
return $promise->then(sub { $new->$method(@result) },
sub { $new->$method(@result) });
}
$new->$method(@result);
();
};

push @{$self->{resolve}}, sub { $cb->('resolve', @_) };
push @{$self->{reject}}, sub { $cb->('reject', @_) };

$self->_defer if $self->{result};

return $new;
}

sub pass { $_[0]->begin->(@_) }

sub race {
Expand Down Expand Up @@ -72,9 +95,9 @@ sub then {
sub wait {
my $self = shift;
return if $self->ioloop->is_running;
$self->once(error => \&_die);
$self->once(finish => sub { shift->ioloop->stop });
$self->ioloop->start;
my $loop = $self->ioloop;
$self->finally(sub { $loop->stop });
$loop->start;
}

sub _clone {
Expand Down Expand Up @@ -114,11 +137,15 @@ sub _step {

$self->{counter} = 0;
if (my $cb = shift @{$self->remaining}) {
eval { $self->$cb(@args); 1 }
or (++$self->{fail} and return $self->remaining([])->emit(error => $@));
unless (eval { $self->$cb(@args); 1 }) {
my $err = $@;
$self->{fail}++;
return $self->remaining([])->reject($err)->emit(error => $err);
}
}

return $self->remaining([])->emit(finish => @args) unless $self->{counter};
return $self->remaining([])->resolve(@args)->emit(finish => @args)
unless $self->{counter};
$self->ioloop->next_tick($self->begin) unless $self->{pending};
return $self;
}
Expand Down Expand Up @@ -392,6 +419,10 @@ Data shared between all L</"steps">.
# Assign multiple values at once
$delay->data(foo => 'test', bar => 23);
=head2 finally
my $new = $delay->finally(sub {...});
=head2 pass
$delay = $delay->pass;
Expand Down
29 changes: 29 additions & 0 deletions t/mojo/delay.t
Expand Up @@ -15,6 +15,14 @@ Mojo::IOLoop->one_tick;
is_deeply \@results, ['hello', 'world'], 'promise resolved';
is_deeply \@errors, [], 'promise not rejected';

# Promise (resolved with finally)
$delay = Mojo::IOLoop::Delay->new;
@results = ();
$delay->finally(sub { @results = @_; 'fail' })->then(sub { push @results, @_ });
$delay->resolve('hello', 'world');
Mojo::IOLoop->one_tick;
is_deeply \@results, ['hello', 'world', 'hello', 'world'], 'promise settled';

# Promise (rejected)
$delay = Mojo::IOLoop::Delay->new;
(@results, @errors) = ();
Expand All @@ -24,6 +32,15 @@ Mojo::IOLoop->one_tick;
is_deeply \@results, [], 'promise not resolved';
is_deeply \@errors, ['bye', 'world'], 'promise rejected';

# Promise (rejected with finally)
$delay = Mojo::IOLoop::Delay->new;
@errors = ();
$delay->finally(sub { @errors = @_; 'fail' })
->then(undef, sub { push @errors, @_ });
$delay->reject('bye', 'world');
Mojo::IOLoop->one_tick;
is_deeply \@errors, ['bye', 'world', 'bye', 'world'], 'promise settled';

# Promise (chained)
$delay = Mojo::IOLoop::Delay->new;
@results = ();
Expand All @@ -45,6 +62,18 @@ $delay2->resolve('works too');
Mojo::IOLoop->one_tick;
is_deeply \@results, ['works too'], 'promise resolved';

# Promise (resolved nested with finally)
$delay = Mojo::IOLoop::Delay->new;
$delay2 = Mojo::IOLoop::Delay->new;
@results = ();
$delay->finally(sub {$delay2})->finally(sub { @results = @_ });
$delay->resolve('pass');
Mojo::IOLoop->one_tick;
is_deeply \@results, [], 'promise not resolved';
$delay2->resolve('fail');
Mojo::IOLoop->one_tick;
is_deeply \@results, ['pass'], 'promise resolved';

# Promise (exception in chain)
$delay = Mojo::IOLoop::Delay->new;
(@results, @errors) = ();
Expand Down

0 comments on commit 96a5717

Please sign in to comment.