NAME
Venus::Future - Future Class
ABSTRACT
Future Class for Perl 5
SYNOPSIS
package main;
use Venus::Future;
my $future = Venus::Future->new;
# bless({...}, 'Venus::Future')
# $future->promise(sub{
# my ($resolve, $reject) = @_;
# $resolve->result(1);
# });
# bless({...}, 'Venus::Future')
# $future->fulfill;
# true
DESCRIPTION
This package provides a framework-agnostic "Future" and implementation of the "Promise/A+" pattern for asynchronous programming. The futures are non-blocking and support "suspend" and "resume" allowing them to be used in any asynchronous operating environment.
INHERITS
This package inherits behaviors from:
INTEGRATES
This package integrates behaviors from:
METHODS
This package provides the following methods:
catch
catch(coderef $on_reject) (Venus::Future)
The catch method registers a rejection handler and returns the future that invokes the handlers.
Since 3.55
- catch example 1
-
# given: synopsis package main; my $catch = $future->catch(sub{ my ($issue) = @_; return $issue; }); # bless(..., "Venus::Future") # $catch->then(sub{...}); # bless(..., "Venus::Future")
- catch example 2
-
# given: synopsis package main; my $catch = $future->catch(sub{ my ($issue) = @_; return $issue; }); # bless(..., "Venus::Future") $future = $future; # bless(..., "Venus::Future") # $future->reject('Oops!'); # bless(..., "Venus::Future")
finally
finally(coderef $on_finally) (Venus::Future)
The finally method registers a finally handler and returns the future that invokes the handlers.
Since 3.55
- finally example 1
-
# given: synopsis package main; my $finally = $future->finally(sub{ my ($data) = @_; return $data; }); # bless(..., "Venus::Future") # $finally->then(sub{...}); # bless(..., "Venus::Future")
- finally example 2
-
# given: synopsis package main; $future->then(sub{ $_ }); my $finally = $future->finally(sub{ my ($data) = @_; $future->{stash} = $data; return $data; }); # bless(..., "Venus::Future") $future = $future; # bless(..., "Venus::Future") # $future->resolve('Hello.'); # bless(..., "Venus::Future")
- finally example 3
-
# given: synopsis package main; $future->then(sub{ $_ }); my $finally = $future->finally(sub{ my ($data) = @_; $future->{stash} = $data; return $data; }); # bless(..., "Venus::Future") $future = $future; # bless(..., "Venus::Future") # $future->reject('Oops!'); # bless(..., "Venus::Future")
fulfill
fulfill() (Venus::Future)
The fulfill method attempts to fulfill the promise by actuating it, or resuming a previously actuated promise, and returns true if the future has been resolved, i.e. the future is either is_fulfilled or is_rejected, and otherwise returns false.
Since 3.55
- fulfill example 1
-
# given: synopsis package main; $future->promise(sub{ # resolve $_[0]->result; }); my $fulfilled = $future->fulfill; # true
- fulfill example 2
-
# given: synopsis package main; $future->promise(sub{ # resolve $_[0]->result; }); $future->fulfill; my $result = $future; # bless(..., "Venus::Future") # $result->is_fulfilled; # true # $result->value; # undef
- fulfill example 3
-
# given: synopsis package main; $future->promise(sub{ # resolve $_[1]->result; }); my $fulfilled = $future->fulfill; # true
- fulfill example 4
-
# given: synopsis package main; $future->promise(sub{ # resolve $_[1]->result; }); $future->fulfill; my $result = $future; # bless(..., "Venus::Future") # $result->is_rejected; # true # $result->issue; # undef
- fulfill example 5
-
# given: synopsis package main; $future->promise(sub{ # resolve $_[0]->result(1); })->then(sub{ return $future->{stash} = $_ * 2; # 2 })->then(sub{ return $future->{stash} = $_ * 2; # 4 })->then(sub{ return $future->{stash} = $_ * 2; # 8 }); $future->fulfill; my $result = $future; # bless(..., "Venus::Future") # $result->is_fulfilled; # true # $result->value; # 1
- fulfill example 6
-
# given: synopsis package main; $future->promise(sub{ # resolve $_[0]->result(1); }); $future->then(sub{ return $future->{stash} = $_ * 2; # 2 }); $future->then(sub{ return $future->{stash} = $_ * 2; # 2 }); $future->then(sub{ return $future->{stash} = $_ * 2; # 2 }); $future->fulfill; my $result = $future; # bless(..., "Venus::Future") # $result->is_fulfilled; # true # $result->value; # 1
- fulfill example 7
-
# given: synopsis package main; my $pending_future = Venus::Future->new; $future->promise(sub{ # resolve $_[0]->result(1); })->then(sub{ return $_ })->then(sub{ return $pending_future; })->then(sub{ return $_ }); $future->fulfill; my @results = ($future, $pending_future); # my $result = $future; # bless(..., "Venus::Future") # $result->is_fulfilled; # false # $result->is_pending; # true # $result->value; # undef # $pending_future->resolve(0); # bless(..., "Venus::Future") # $pending_future->is_fulfilled; # true # $result->fulfill; # true # $result->is_fulfilled; # true
- fulfill example 8
-
# given: synopsis package Thenable; use Venus::Class; sub then { my ($self, $resolve, $reject) = @_; $resolve->(100); } package main; my $thenable_object = Thenable->new; $future->promise(sub{ # resolve $_[0]->result(1); })->then(sub{ return $_ })->then(sub{ return $thenable_object; })->then(sub{ return $future->{stash} = $_ }); $future->fulfill; my @results = ($future, $thenable_object); # my $result = $future; # bless(..., "Venus::Future") # $result->is_fulfilled; # true # $result->value; # 1
is
is(string $name) (boolean)
The is method take a name and dispatches to the corresponding is_$name
method and returns the result.
Since 3.55
- is example 1
-
# given: synopsis package main; $future->resolve; my $is_fulfilled = $future->is('fulfilled'); # true
- is example 3
-
# given: synopsis package main; $future->reject; my $is_rejected = $future->is('rejected'); # true
is_fulfilled
is_fulfilled() (boolean)
The is_fulfilled method returns true if the future has been fulfilled, otherwise returns false.
Since 3.55
- is_fulfilled example 1
-
# given: synopsis package main; my $is_fulfilled = $future->is_fulfilled; # false
- is_fulfilled example 2
-
# given: synopsis package main; $future->resolve; my $is_fulfilled = $future->is_fulfilled; # true
- is_fulfilled example 3
-
# given: synopsis package main; $future->reject; my $is_fulfilled = $future->is_fulfilled; # false
is_pending
is_pending() (boolean)
The is_pending method returns true if the future has remained pending, otherwise returns false.
Since 3.55
- is_pending example 2
-
# given: synopsis package main; $future->resolve; my $is_pending = $future->is_pending; # false
- is_pending example 3
-
# given: synopsis package main; $future->reject; my $is_pending = $future->is_pending; # false
is_promised
is_promised() (boolean)
The is_promised method returns true if the future a registered promise, otherwise returns false.
Since 3.55
- is_promised example 1
-
# given: synopsis package main; my $is_promised = $future->is_promised; # false
- is_promised example 2
-
# given: synopsis package main; $future->promise; my $is_promised = $future->is_promised; # false
- is_promised example 3
-
# given: synopsis package main; $future->promise(sub{$_[0]->result}); my $is_promised = $future->is_promised; # true
is_rejected
is_rejected() (boolean)
The is_rejected method returns true if the future has been rejected, otherwise returns false.
Since 3.55
- is_rejected example 1
-
# given: synopsis package main; my $is_rejected = $future->is_rejected; # false
- is_rejected example 2
-
# given: synopsis package main; $future->resolve; my $is_rejected = $future->is_rejected; # false
- is_rejected example 3
-
# given: synopsis package main; $future->reject; my $is_rejected = $future->is_rejected; # true
issue
issue() (any)
The issue method returns the result of the "reject" operation once the future has been rejected.
Since 3.55
- issue example 1
-
# given: synopsis package main; my $issue = $future->issue; # undef # $future->is_pending # true
- issue example 2
-
# given: synopsis package main; $future->reject(0); my $issue = $future->issue; # 0 # $future->is_rejected # true
- issue example 3
-
# given: synopsis package main; $future->reject({fail => 1}); my $issue = $future->issue; # {fail => 1} # $future->is_rejected # true
new
new(any @args) (Venus::Future)
The new method instantiates this package and returns a new instance.
Since 3.55
- new example 2
-
package main; my $future = Venus::Future->new(sub{ my ($resolve, $reject) = @_; $resolve->result('okay'); }); # bless(..., "Venus::Future") # $future->is('fulfilled'); # true # $future->value; # 'okay'
- new example 3
-
package main; my $future = Venus::Future->new(promise => sub{ my ($resolve, $reject) = @_; $reject->result('boom'); }); # bless(..., "Venus::Future") # $future->is('rejected'); # true # $future->issue; # 'boom'
promise
promise(coderef $code) (Venus::Future)
The promise method registers a callback executed by the "fulfill" method, which is provided two arguments; the first argument being a Venus::Try instance representing a resolve
operaiton; the second argument being a Venus::Try instance representing a reject
operaiton; and returns the invocant.
Since 3.55
- promise example 1
-
# given: synopsis package main; $future = $future->promise(sub{ my ($resolve, $reject) = @_; $resolve->result('pass'); }); # bless(..., "Venus::Future") # $future->fulfill; # true
- promise example 2
-
# given: synopsis package main; $future = $future->promise(sub{ my ($resolve, $reject) = @_; $reject->result('fail'); }); # bless(..., "Venus::Future") # $future->fulfill; # true
reject
reject(any $issue) (Venus::Future)
The reject method cascades a rejection operation causes the future to be rejected, and returns the invocant.
Since 3.55
- reject example 1
-
# given: synopsis package main; my $rejected = $future->reject; # bless(..., "Venus::Future") # $rejected->status # "rejected" # $rejected->issue # undef
- reject example 2
-
# given: synopsis package main; my $rejected = $future->reject('Oops!'); # bless(..., "Venus::Future") # $rejected->status # "rejected" # $rejected->issue # "Oops!"
resolve
resolve(any $value) (Venus::Future)
The resolve method cascades a rejection operation causes the future to be rejected, and returns the invocant.
Since 3.55
- resolve example 1
-
# given: synopsis package main; my $fulfilled = $future->resolve; # bless(..., "Venus::Future") # $fulfilled->status # "fulfilled" # $fulfilled->value # undef
- resolve example 2
-
# given: synopsis package main; my $fulfilled = $future->resolve('Great!'); # bless(..., "Venus::Future") # $fulfilled->status # "fulfilled" # $fulfilled->value # "Great!"
status
status() (any)
The status method returns the status of the future. Valid statuses are fulfilled
, pending
, and rejected
.
Since 3.55
- status example 2
-
# given: synopsis package main; $future->resolve(0); my $status = $future->status; # "fulfilled"
- status example 3
-
# given: synopsis package main; $future->reject(0); my $status = $future->status; # "rejected"
then
then(coderef $fulfill, coderef $reject) (Venus::Future)
The then method registers fulfillment and rejection handlers and returns the future that invokes the handlers.
Since 3.55
- then example 1
-
# given: synopsis package main; my $new_future = $future->then(sub{ # fulfillment handler $_ }); # "Venus::Future" # $new_future->is_pending; # true
- then example 2
-
# given: synopsis package main; my $new_future = $future->then(sub{ # fulfillment handler $_ }, sub{ # rejection handler $_ }); # "Venus::Future" # $new_future->is_pending; # true
- then example 3
-
# given: synopsis package main; my $new_future = $future->then(undef, sub{ # rejection handler $_ }); # "Venus::Future" # $new_future->is_pending; # true
- then example 4
-
# given: synopsis package main; my $new_future = $future->then(sub{ # fulfillment handler $_ }); # "Venus::Future" # $new_future->is_pending; # true $future = $future; # "Venus::Future" # $new_future->is_pending; # true
- then example 5
-
# given: synopsis package main; my $new_future = $future->then(sub{ # fulfillment handler $_ }, sub{ # rejection handler $_ }); # "Venus::Future" # $new_future->is_pending; # true $future = $future; # "Venus::Future" # $new_future->is_pending; # true
- then example 6
-
# given: synopsis package main; my $new_future = $future->then(undef, sub{ # rejection handler $_ }); # "Venus::Future" # $new_future->is_pending; # true $future = $future; # "Venus::Future" # $new_future->is_pending; # true
value
value() (any)
The value method returns the result of the "resolve" operation once the future has been fulfilled.
Since 3.55
- value example 1
-
# given: synopsis package main; my $value = $future->value; # undef # $future->is_pending # true
- value example 2
-
# given: synopsis package main; $future->resolve(1); my $value = $future->value; # 1 # $future->is_fulfilled # true
- value example 3
-
# given: synopsis package main; $future->resolve({pass => 1}); my $value = $future->value; # {pass => 1} # $future->is_fulfilled # true
wait
wait(number $timeout) (Venus::Future)
The wait method blocks the execution of the current process until a value is received. If a timeout is provided, execution will be blocked until a value is received or the wait time expires. If a timeout of 0
is provided, execution will not be blocked. If no timeout is provided at all, execution will block indefinitely.
Since 3.55
- wait example 1
-
# given: synopsis package main; $future->promise(sub{ # resolve $_[0]->result; }); $future = $future->wait(0); # bless(..., "Venus::Future") # $future->is_fulfilled; # true
- wait example 2
-
# given: synopsis package main; $future->promise(sub{ # never fulfilled }); $future->wait(1); # Exception! (isa Venus::Future::Error) (see error_on_timeout)
ERRORS
This package may raise the following errors:
- error:
error_on_timeout
-
This package may raise an error_on_timeout exception.
example 1
# given: synopsis; my $input = { throw => 'error_on_timeout', timeout => 10, }; my $error = $future->try('error', $input)->error->result; # my $name = $error->name; # "on_timeout" # my $message = $error->render; # "Future timed-out after 10 seconds" # my $timeout = $error->stash('timeout'); # 10
AUTHORS
Awncorp, awncorp@cpan.org
LICENSE
Copyright (C) 2022, Awncorp, awncorp@cpan.org
.
This program is free software, you can redistribute it and/or modify it under the terms of the Apache license version 2.0.