Skip to content

Instantly share code, notes, and snippets.

/thenable.diff Secret

Created October 22, 2017 00:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/5b2af60a51943afb4944ed7f7d9c8b3c to your computer and use it in GitHub Desktop.
Save anonymous/5b2af60a51943afb4944ed7f7d9c8b3c to your computer and use it in GitHub Desktop.
diff --git a/lib/Mojo/IOLoop/Delay.pm b/lib/Mojo/IOLoop/Delay.pm
index b918b1fcf..27c8e03a4 100644
--- a/lib/Mojo/IOLoop/Delay.pm
+++ b/lib/Mojo/IOLoop/Delay.pm
@@ -18,12 +18,27 @@ sub data { Mojo::Util::_stash(data => @_) }
sub pass { $_[0]->begin->(@_) }
+sub reject { shift->_finish(error => @_) }
+sub resolve { shift->_finish(finish => @_) }
+
sub steps {
my $self = shift->remaining([@_]);
$self->ioloop->next_tick($self->begin);
return $self;
}
+sub then {
+ my ($self, $finish, $error) = @_;
+
+ my $next = $self->new(ioloop => $self->ioloop);
+ $self->on(finish => sub { shift; $next->resolve(@_) });
+ $self->on(error => sub { shift; $next->reject(@_) });
+ $next->on(finish => $finish) if $finish;
+ $next->on(error => $error) if $error;
+
+ return $next;
+}
+
sub wait {
my $self = shift;
return if $self->ioloop->is_running;
@@ -34,22 +49,27 @@ sub wait {
sub _die { $_[0]->has_subscribers('error') ? $_[0]->ioloop->stop : die $_[1] }
+sub _finish {
+ my ($self, $event) = (shift, shift);
+ $self->{done} ? return $self : $self->{done}++;
+ return $self->remaining([])->emit($event => @_);
+}
+
sub _step {
my ($self, $id, $offset, $len) = (shift, shift, shift, shift);
$self->{args}[$id]
= [@_ ? defined $len ? splice @_, $offset, $len : splice @_, $offset : ()];
- return $self if $self->{fail} || --$self->{pending} || $self->{lock};
+ return $self if $self->{done} || --$self->{pending} || $self->{lock};
local $self->{lock} = 1;
my @args = map {@$_} @{delete $self->{args}};
$self->{counter} = 0;
if (my $cb = shift @{$self->remaining}) {
- eval { $self->$cb(@args); 1 }
- or (++$self->{fail} and return $self->remaining([])->emit(error => $@));
+ eval { $self->$cb(@args); 1 } or $self->reject($@);
}
- return $self->remaining([])->emit(finish => @args) unless $self->{counter};
+ return $self->resolve(@args) unless $self->{counter};
$self->ioloop->next_tick($self->begin) unless $self->{pending};
return $self;
}
diff --git a/t/mojo/delay.t b/t/mojo/delay.t
index 35e51d1a5..210da8ba8 100644
--- a/t/mojo/delay.t
+++ b/t/mojo/delay.t
@@ -20,6 +20,17 @@ $end2->();
$delay->wait;
is_deeply \@results, [1, 1], 'right results';
+# Thenable
+my ($resolve, $reject, $resolve2, $reject2);
+$delay = Mojo::IOLoop::Delay->new;
+my $delay2 = $delay->then(sub { $resolve = pop }, sub { $reject = pop });
+$delay2->then(sub { $resolve2 = pop }, sub { $reject2 = pop });
+$delay->resolve('works');
+is $resolve, 'works', 'right result';
+is $resolve2, 'works', 'right result';
+is $reject, undef, 'no result';
+is $reject2, undef, 'no result';
+
# Argument splicing
$delay = Mojo::IOLoop::Delay->new;
Mojo::IOLoop->next_tick($delay->begin);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment