Skip to content

Commit 43b8eb8

Browse files
committed
document Promise
1 parent 8000e26 commit 43b8eb8

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

lib/Type/Promise.pod

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
=begin pod
2+
3+
=TITLE class Promise
4+
5+
=SUBTITLE Container for results from asynchronous computations
6+
7+
my enum PromiseStatus (:Planned(0), :Kept(1), :Broken(2));
8+
class Promise { ... }
9+
10+
A I<Promise> is used to handle the result of a computation that might not have
11+
finished. It allows the user to execute code once the computation is done
12+
(with the C<then> method), execution after a time delay (with C<in>),
13+
combining promises, and waiting for results.
14+
15+
my $p = Promise.start({ sleep 2; 42});
16+
$p.then({ say .result }); # will print 42 once the block finished
17+
say $p.status; # Planned
18+
$p.result; # waits for the computation to finish
19+
20+
21+
=head1 Methods
22+
23+
=head2 method start
24+
25+
sub start(&code);
26+
method start(Promise:U: &code, :$scheduler = $*SCHEDULER) returns Promise:D
27+
28+
Creates a new Promise that runs the given code object. The promise will be
29+
kept when the code terminates normally, or broken if it throws an exception.
30+
The return value or exception can be inspected with the C<result> method.
31+
32+
The scheduler that handles this promise can be passed as a named argument.
33+
34+
# these two are equivalent:
35+
my $p1 = Promise.start({ do something here });
36+
my $p2 = start { do something here };
37+
38+
=head2 method in
39+
40+
method in(Promise:U: $seconds, :$scheduler = $*SCHEDULER) returns Promise:D
41+
42+
Creates a new Promise that will be kept in C<$seconds> seconds, or later.
43+
44+
my $p = Promise.in(5).then({ say "5 seconds later" });
45+
# do other stuff here
46+
47+
await $p; # wait here until the 5 seconds are over
48+
49+
=head2 method allof
50+
51+
method allof(Promise:U: *@promises) returns Promise:D
52+
53+
Returns a new promise that will be kept when all he promises passed as
54+
arguments are keept, and that will be broken as soon as any of the argument
55+
promises is broken.
56+
57+
my @promises;
58+
for 1..5 -> $t {
59+
push @promises, start {
60+
sleep $t;
61+
die "OH NOEZ" if rand < 0.2;
62+
};
63+
}
64+
my $all-successful = Promise.allof(@promises);
65+
await $all-successful;
66+
67+
=head2 method anyof
68+
69+
method anyof(Promise:U: *@promises) returns Promise:D
70+
71+
Returns a new promise that will be kept when the any of the promises passed as
72+
arguments are kept, and will be broken when all of the argument promises are
73+
broken.
74+
75+
(TODO: example)
76+
77+
=head2 method then
78+
79+
method then(Promise:D: &code)
80+
81+
Schedules a piece of code to be run after the invocant has been kept or
82+
broken, and returns a new promise for this computation. In other words,
83+
creates a chained promise.
84+
85+
my $timer = Promise.in(2);
86+
my $after = $timer.then({ say "2 seconds are over!"; 'result' });
87+
say $after.result; # 2 seconds are over
88+
# result
89+
90+
=head2 method keep
91+
92+
multi method keep(Promise:D:);
93+
multi method keep(Promise:D: \result);
94+
95+
Keeps a promise, optionally setting the result. If no result is passed, the
96+
result will be C<True>.
97+
98+
Throws an exception of type X::Promise::Vowed if a vow has already been
99+
taken. See method C<vow> for more information.
100+
101+
my $p = Promise.new;
102+
103+
if Bool.pick {
104+
$p.keep;
105+
}
106+
else {
107+
$p.break;
108+
}
109+
110+
=head2 method break
111+
112+
multi method break(Promise:D:);
113+
multi method break(Promise:D: \result);
114+
115+
Breaks a promise, optionally setting the result. If no result is passed, the
116+
result will be C<False>.
117+
118+
Throws an exception of type X::Promise::Vowed if a vow has already been
119+
taken. See method C<vow> for more information.
120+
121+
my $p = Promise.new;
122+
123+
$p.break('sorry');
124+
say $p.status; # Broken
125+
say $p.cause; # sorry
126+
127+
=head2 method result
128+
129+
method result(Promise:D)
130+
131+
Waits for the promise to be kept or broken. If it is kept, returns the result;
132+
otherwise throw the result as an exception.
133+
134+
=head2 method cause
135+
136+
method cause(Promise:D)
137+
138+
If the promise was broken, returns the result (or exception). Otherwise, throws
139+
an exception of type C<X::Promise::CauseOnlyValidOnBroken>.
140+
141+
=head2 method Bool
142+
143+
multi method Bool(Promise:D:)
144+
145+
Returns C<True> for a kept or broken promise, and C<False> for one in state
146+
C<Planned>.
147+
148+
=head2 method status
149+
150+
151+
method status(Promise:D) returns PromiseStatus
152+
153+
Returns the current state of a promise, so C<Kept>, C<Broken> or C<Planned>.
154+
155+
=head2 method scheduler
156+
157+
method scheduler(Promise:D:)
158+
159+
Returns the scheduler that manages the promise.
160+
161+
=head2 method vow
162+
163+
my class Vow {
164+
has Promise $.promise;
165+
method keep() { ... }
166+
method break() { ... }
167+
}
168+
method vow(Promise:D:)
169+
170+
Returns an object that holds the sole authority over keeping or breaking a
171+
promise. Calling C<keep> or C<break> on a promise that has vow taken throws an
172+
exception of type C<X::Promise::Vowed>.
173+
174+
my $p = Promise.new;
175+
my $vow = $p.vow;
176+
$vow.keep;
177+
say $p.status; # Kept
178+
179+
=end pod

0 commit comments

Comments
 (0)