NAME

Promise::ES6 - ES6-style promises in Perl

SYNOPSIS

my $promise = Promise::ES6->new( sub {
    my ($resolve_cr, $reject_cr) = @_;

    # ..
} );

my $promise2 = $promise->then( sub { .. }, sub { .. } );

my $promise3 = $promise->catch( sub { .. } );

my $promise4 = $promise->finally( sub { .. } );

my $resolved = Promise::ES6->resolve(5);
my $rejected = Promise::ES6->reject('nono');

my $all_promise = Promise::ES6->all( \@promises );

my $race_promise = Promise::ES6->race( \@promises );

DESCRIPTION

This module provides a Perl implementation of promises, a useful pattern for coordinating asynchronous tasks.

Unlike most other promise implementations on CPAN, this module mimics ECMAScript 6’s Promise interface. As the SYNOPSIS above shows, you can thus use patterns from JavaScript in Perl with only minimal changes needed to accommodate language syntax.

This is a rewrite of an earlier module, Promise::Tiny. It fixes several bugs and superfluous dependencies in the original.

INTERFACE NOTES

COMPATIBILITY

This module considers any object that has a then() method to be a promise. Note that, in the case of Future, this will yield a “false-positive”, as Future is not compatible with promises.

(See Promise::ES6::Future for more tools to interact with Future.)

UNHANDLED REJECTIONS

This module’s handling of unhandled rejections has changed over time. The current behavior is: if any rejected promise is DESTROYed without first having received a failure callback, a warning is thrown.

SYNCHRONOUS OPERATION

In JavaScript, the following …

Promise.resolve().then( () => console.log(1) );
console.log(2);

… will log 2 then 1 because JavaScript’s then() defers execution of its callbacks until the end of the current iteration through JavaScript’s event loop.

Perl, of course, has no built-in event loop. This module’s then() method, thus, when called on a promise that is already “settled” (i.e., not pending), will run the appropriate callback immediately. That means that this:

Promise::ES6->resolve(0)->then( sub { print 1 } );
print 2;

… will print 12 instead of 21.

This is an intentional divergence from the Promises/A+ specification. A key advantage of this design is that Promise::ES6 instances can abstract over whether a given function works synchronously or asynchronously.

If you want a Promises/A+-compliant implementation, look at Promise::ES6::IOAsync, Promise::ES6::Mojo, or Promise::ES6::AnyEvent in this distribution. CPAN provides other alternatives.

CANCELLATION

Promises have never provided a standardized solution for cancellation—i.e., aborting an in-process operation. So, if you need this functionality, you’ll have to implement it yourself. Two ways of doing this are:

You’ll need to decide if it makes more sense for your application to leave a canceled query in the “pending” state or to “settle” (i.e., resolve or reject) it. All things being equal, I feel the first approach is the most intuitive.

MEMORY LEAKS

It’s easy to create inadvertent memory leaks using promises in Perl. Here are a few “pointers” (heh) to bear in mind:

SEE ALSO

If you’re not sure of what promises are, there are several good introductions to the topic. You might start with this one.

Promise::XS is a lot like this library but implemented mostly in XS for speed. It derives from AnyEvent::XSPromises.

Promises is another pure-Perl Promise implementation.

Future fills a role similar to that of promises.

CPAN contains a number of other modules that implement promises. I think mine are the nicest :), but YMMV. Enjoy!

LICENSE & COPYRIGHT

Copyright 2019-2020 Gasper Software Consulting.

This library is licensed under the same terms as Perl itself.