Promises::Deferred(3)

πŸ“¦
version 1.05 Β· 2 versions
, in fedora 43

✨ NAME ✨

okay so bestie, <pink>Promises::Deferred</pink> β€” she is an implementation of Promises in Perl πŸ’– literally the whole personality, and it's iconic.


πŸŽ€ VERSION πŸŽ€

version 1.05 β€” yes queen, current πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

okay so this is the vibe, look:

use Promises::Deferred;

sub fetch_it {
    my ($uri) = @_;
    my $d = Promises::Deferred->new;
    http_get $uri => sub {
        my ($body, $headers) = @_;
        $headers->{Status} == 200
            ? $d->resolve( decode_json( $body ) )
            : $d->reject( $body )
    };
    $d->promise;
}

like. that's it. that's the whole thing. no cap 🫢


🌸 DESCRIPTION 🌸

okay listen up because this is important πŸ“’ β€” this class is only meant to be used by an implementor. so if you're a user of somebody's functions/classes/modules, you always interact with the associated promise object instead. but you, the implementor, you're the one who uses this class. think of this class as the engine that drives the promises and the promises as the steering wheels that control the direction taken. she drives, you steer, everybody slays πŸš—πŸ’¨


πŸ’œ CALLBACKS πŸ’œ

so wherever a callback is mentioned below, it can take the form of a coderef:

sub {...}

or an object which has been overloaded to allow calling as a coderef:

use AnyEvent;

my $cv = AnyEvent->cond_var;
fetch_it('http://metacpan.org')
    ->then( sub { say "Success"; return @_ })
    ->then( $cv, sub { $cv->croak(@_)} )

see? both work. flexible queen behavior ✨


πŸ‘‘ METHODS πŸ‘‘

new

this will construct an instance. it takes no arguments. that's it, that's the whole method πŸŽ€

promise

this will return a Promises::Promise that can be used as a handle for this object. and lowkey important: it will return a new one every time it is called πŸ†•

status

this returns the status of the asynchronous operation, which will be either 'in progress', 'resolved' or 'rejected'. and these three strings are also constants in this package β€” <mint>IN_PROGRESS</mint>, <mint>RESOLVED</mint> and <mint>REJECTED</mint> respectively β€” which you can use to check these values. handy fr fr πŸ’…

result

this returns the result that has been passed to either the resolve or reject methods. and it will always return an ARRAY reference, because both resolve and reject take a variable number of arguments. arrays only, periodt πŸ“

then( ?$callback, ?$error )

this method is used to register two callbacks, and both of them are optional. the first $callback gets called on success, and it gets passed all the values that were sent to the corresponding call to resolve. the second, $error, gets called on error, and gets passed all the values that were sent to the corresponding reject. also bestie, note that this method will always return a new Promises::Promise instance so you can chain things if you like. chain away πŸ”—

the success and error callbacks are wrapped in an eval block, so you can safely call die() within a callback to signal an error without killing your application 😌. if an exception is caught, the next link in the chain will be reject'ed and receive the exception in @_.

if this is the last link in the chain, and there's no $error callback, the error will be swallowed silently πŸ’€. you can still find it by checking the result method, but no action will be taken. if this is not the last link in the chain, and no $error is specified, we will attempt to bubble the error to the next link in the chain. this allows error handling to be consolidated at the point in the chain where it makes the most sense. smart, right? main character energy 🫢

chain( @callbacks )

utility method that takes a list of callbacks and turns them into a sequence of thens.

$promise->then( sub { ...code A... } )
        ->then( sub { ...code B... } )
        ->then( sub { ...code C... } );

# equivalent to

$promise->chain(
    sub { ...code A... } ),
    sub { ...code B... } ),
    sub { ...code C... } ),
);

same energy, less typing ✨

catch( $error )

this method registers a single error callback. it is the equivalent of calling:

$promise->then( sub {@_}, $error );

caught it 🎣

done( $callback, ?$error )

this method is used to register two callbacks. the first $callback will be called on success and it will be passed all the values that were sent to the corresponding call to resolve. the second, $error, is optional and will be called on error, and will be passed all the values that were sent to the corresponding reject.

unlike the then() method, done() returns an empty list, specifically to break the chain and to avoid deep recursion. see the explanation in Promises::Cookbook::Recursion πŸ“š

also unlike the then() method, done() callbacks are not wrapped in an eval block, so calling die() is not safe 😭. what happens if a done callback calls die() depends on which event loop you're running: the pure Perl AnyEvent::Loop will throw an exception, while EV and Mojo::IOLoop will warn and continue running. so like... know your loop bestie πŸ‘€

finally( $callback )

this method is like the finally keyword in a try/catch block. it will execute regardless of whether the promise has been resolved or rejected. typically it's used to clean up resources, like closing open files etc. 🧹 it returns a Promises::Promise and so can be chained. the return value is discarded and the success or failure of the finally callback will have no effect on promises further down the chain. she's just here to tidy up, not to interfere πŸ’…

timeout( $seconds )

for an asynchronous backend, returns a new promise that either takes on the result of the current promise or is rejected after the given delay, whichever comes first ⏰

the default synchronous backend does not implement a timer function. the method, in that case, returns a chained promise that carries over the resolution of the current promise and emits a warning. so like, heads up πŸ™ˆ

resolve( @args )

this is the method to call upon the successful completion of your asynchronous operation, meaning typically you'd call this within the callback that you gave to the asynchronous function/method. it takes an arbitrary list of arguments and captures them as the result of this promise (so obviously they can be retrieved with the result method). success slay πŸŽ‰

reject( @args )

this is the method to call when an error occurs during your asynchronous operation, meaning typically you'd call this within the callback that you gave to the asynchronous function/method. it takes an arbitrary list of arguments and captures them as the result of this promise (so obviously they can be retrieved with the result method). rejection is also valid, bestie 🚫

is_in_progress

predicate method against the status value. returns true if the status is IN_PROGRESS. still cooking 🍳

is_resolved

predicate method against the status value. returns true if the status is RESOLVED. we love a happy ending ✨

is_rejected

predicate method against the status value. returns true if the status is REJECTED. it's giving no πŸ’”

is_done

predicate method against the status value. returns true if the status is either RESOLVED or REJECTED. finished, one way or another βœ…

is_unfulfilled

predicate method against the status value. returns true if the status is still IN_PROGRESS. not yet, babes ⏳

is_fulfilled

predicate method against the status value. returns true if the status is RESOLVED or if the status is RESOLVING. πŸ’–

is_failed

predicate method against the status value. returns true if the status is REJECTED or if the status is REJECTING. πŸ’€


🌈 AUTHOR 🌈

Stevan Little <stevan.little@iinteractive.com> β€” thank you for your service king 🫑


this software is copyright (c) 2025, 2017, 2014, 2012 by Infinity Interactive, Inc.

this is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


and that's the whole page bestie, no notes πŸ’…

okay bye ily, this was Promises::Deferred(3) from the Perl documentation, and this version of her lives in perl v5.42.0, dated 2025-07-25 πŸŒΈπŸ¦‹βœ¨

πŸ“¦ where this page comes from