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_fulfilled
is_fulfilled() (boolean)
The is_fulfilled method returns true if the future has been fulfilled, otherwise returns false.
Since 3.55
is_pending
is_pending() (boolean)
The is_pending method returns true if the future has remained pending, otherwise returns false.
Since 3.55
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 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
issue
issue() (any)
The issue method returns the result of the "reject" operation once the future has been rejected.
Since 3.55
- 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
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 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.