Skip to content

Instantly share code, notes, and snippets.

@pangyre
Created May 1, 2013 18:00
Show Gist options
  • Save pangyre/5496983 to your computer and use it in GitHub Desktop.
Save pangyre/5496983 to your computer and use it in GitHub Desktop.
BEGIN {
package Promise;
use Moo;
my %STATES = map { $_ => 1 } qw/ PENDING FULFILLED REJECTED /;
has "value" => is => "ro", writer => "_value";
has "reason" => is => "ro", writer => "_reason";
has [qw/ on_fulfill on_reject /] =>
is => "ro",
default => sub { [] },
;
has "state" =>
is => "ro",
default => sub { "PENDING" },
writer => "_state",
isa => sub { die "Bad state: $_[0]" unless $STATES{$_[0]} },
;
sub fulfill {
my $self = shift;
$self->_value( my $value = shift );
return unless $self->state eq "PENDING";
$self->_state("FULFILLED");
$_->($value) for @{ $self->on_fulfill };
}
sub reject {
my $self = shift;
$self->_reason( my $reason = shift );
return unless $self->state eq "PENDING";
$self->_state("REJECTED");
$_->($reason) for @{ $self->on_reject };
}
sub then {
my $self = shift;
if ( my $fulfill = shift )
{
die "$fulfill is not a CODE reference"
unless ref $fulfill eq "CODE";
push @{ $self->on_fulfill }, $fulfill;
$fulfill->($self->value)
if $self->state eq "FULFILLED";
}
if ( my $reject = shift )
{
die "$reject is not a CODE reference"
unless ref $reject eq "CODE";
push @{ $self->on_reject }, $reject;
$reject->($self->value)
if $self->state eq "REJECTED";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment