Anthony Johnson
and 1 contributors

NAME

AnyEvent::Promise - Evented promises

VERSION

Version 0.01

SYNOPSIS

Avoid the evented pyramid of doom!

    use AnyEvent::Promise;
    use AnyEvent::Redis;

    my $redis = AnyEvent::Redis->new();

    my $p = promise(sub {
        $redis->get('test');
    })->then(sub {
        $redis->set('test', shift);
    })->then(sub {
        $redis->get('test');
    })->then(sub {
        say shift;
    })->catch(sub {
        say 'I failed!';
        say @_;
    })->fulfill;

DESCRIPTION

AnyEvent::Promise allows evented interfaces to be chained, taking away some of the redundancy of layering AnyEvent condition variable callbacks.

A promise is created using AnyEvent::Promise::new or the exported "promise" helper function. These will both return a promise instance and add the callback function as the start of the promise chain. Each call to "then" on the promise instance will add another subroutine which returns a condition variable to the chain.

The promise callback chain won't start until "condvar" or "fulfill" is called on the instance. Calling "condvar" or "cv" will start the callback chain and return the promise guarding condvar, which is fulfilled after the last callback on the chain returns. Similarily, "fulfill" will start the chain, but will block until the guarding condvar is fulfilled.

Errors in the callbacks can be caught by setting an exception handler via the "catch" method on the promise instance. This method will catch exceptions raised from AnyEvent objects and exceptions raised in blocks provided to "then". If an error is encountered in the chain, an exception will be thrown and the rest of the chain will be skipped, jumping straight to the catch callback.

EXPORT

promise($cb)

Start promise chain with callback $cb. This function is a shortcut to AnyEvent::Promise::new, and returns a promise object with the callback attached.

METHODS

new($cb)

Create an instance of a promise, start the chain off with callback $cb. See "then" for information on passing in a callback and condvar.

then($cb)

Add callback $cb on to the promise chain.

This callback will receive the return of the previous callback -- i.e. the callback will receive the value sent by the previous condvar directly. In order to continue the promise chain, the callback should return a condvar.

Instead of:

    my $cv = $redis->get('test');
    $cv->cb(sub {
        my $ret = shift->recv;
        my $cv2 = $redis->set('test', $ret);
        $cv2->cb(sub {
            my $cv3 = $redis->get('test');
            $cv3->cb(sub {
                my $ret3 = shift->recv;
                printf("Got a value: %s\n", $ret3);
            });
        });
    });
    $cv->recv;

.. a promise chain can be used, by chaining calls to the "then" method:

    my $promise = AnyEvent::Promise->new(sub {
        $redis->get('test');
    })->then(sub {
        my $val = shift;
        $redis->set('test', $val);
    })->then(sub {
        $redis->get('test');
    })->then(sub {
        my $val = shift;
        printf("Got a value: %s\n", $val)
    })->fulfill;

catch($cb)

Catch raised errors in the callback chain. Exceptions in the promise chain will jump up to this catch callback, bypassing any other callbacks in the promise chain. The error caught by Try::Tiny will be sent as arguments to the callback $cb.

condvar(...)

Trigger the start of the promise chain and return the guard condvar from the promise. The guard condvar is fulfilled either after the last callback returns or an exception is encountered somewhere in the chain.

All arguments passed into "condvar" are sent to the first condvar in the promise chain.

cv(...)

Alias of "condvar"

fulfill(...)

Similar to "condvar", trigger the start of the promise chain, but recv on the returned condvar as well.

AUTHOR

Anthony Johnson, <aj at ohess.org>

LICENSE AND COPYRIGHT

Copyright 2013 Anthony Johnson.

This program is distributed under the MIT (X11) License: http://www.opensource.org/licenses/mit-license.php

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.