1Mojo::Promise(3)      User Contributed Perl Documentation     Mojo::Promise(3)
2
3
4

NAME

6       Mojo::Promise - Promises/A+
7

SYNOPSIS

9         use Mojo::Promise;
10         use Mojo::UserAgent;
11
12         # Wrap continuation-passing style APIs with promises
13         my $ua = Mojo::UserAgent->new;
14         sub get {
15           my $promise = Mojo::Promise->new;
16           $ua->get(@_ => sub {
17             my ($ua, $tx) = @_;
18             my $err = $tx->error;
19             if   (!$err || $err->{code}) { $promise->resolve($tx) }
20             else                         { $promise->reject($err->{message}) }
21           });
22           return $promise;
23         }
24
25         # Perform non-blocking operations sequentially
26         get('https://mojolicious.org')->then(sub {
27           my $mojo = shift;
28           say $mojo->res->code;
29           return get('https://metacpan.org');
30         })->then(sub {
31           my $cpan = shift;
32           say $cpan->res->code;
33         })->catch(sub {
34           my $err = shift;
35           warn "Something went wrong: $err";
36         })->wait;
37
38         # Synchronize non-blocking operations (all)
39         my $mojo = get('https://mojolicious.org');
40         my $cpan = get('https://metacpan.org');
41         Mojo::Promise->all($mojo, $cpan)->then(sub {
42           my ($mojo, $cpan) = @_;
43           say $mojo->[0]->res->code;
44           say $cpan->[0]->res->code;
45         })->catch(sub {
46           my $err = shift;
47           warn "Something went wrong: $err";
48         })->wait;
49
50         # Synchronize non-blocking operations (race)
51         my $mojo = get('https://mojolicious.org');
52         my $cpan = get('https://metacpan.org');
53         Mojo::Promise->race($mojo, $cpan)->then(sub {
54           my $tx = shift;
55           say $tx->req->url, ' won!';
56         })->catch(sub {
57           my $err = shift;
58           warn "Something went wrong: $err";
59         })->wait;
60

DESCRIPTION

62       Mojo::Promise is a Perl-ish implementation of Promises/A+
63       <https://promisesaplus.com> and a superset of ES6 Promises
64       <https://duckduckgo.com/?q=n%20Promise>.
65

STATES

67       A promise is an object representing the eventual completion or failure
68       of a non-blocking operation. It allows non-blocking functions to return
69       values, like blocking functions. But instead of immediately returning
70       the final value, the non-blocking function returns a promise to supply
71       the value at some point in the future.
72
73       A promise can be in one of three states:
74
75       pending
76         Initial state, neither fulfilled nor rejected.
77
78       fulfilled
79         Meaning that the operation completed successfully.
80
81       rejected
82         Meaning that the operation failed.
83
84       A pending promise can either be fulfilled with a value or rejected with
85       a reason. When either happens, the associated handlers queued up by a
86       promise's "then" method are called.
87

ATTRIBUTES

89       Mojo::Promise implements the following attributes.
90
91   ioloop
92         my $loop = $promise->ioloop;
93         $promise = $promise->ioloop(Mojo::IOLoop->new);
94
95       Event loop object to control, defaults to the global Mojo::IOLoop
96       singleton.  Note that this attribute is weakened.
97

METHODS

99       Mojo::Promise inherits all methods from Mojo::Base and implements the
100       following new ones.
101
102   all
103         my $new = Mojo::Promise->all(@promises);
104
105       Returns a new Mojo::Promise object that either fulfills when all of the
106       passed Mojo::Promise objects have fulfilled or rejects as soon as one
107       of them rejects. If the returned promise fulfills, it is fulfilled with
108       the values from the fulfilled promises in the same order as the passed
109       promises. This method can be useful for aggregating results of multiple
110       promises.
111
112   catch
113         my $new = $promise->catch(sub {...});
114
115       Appends a rejection handler callback to the promise, and returns a new
116       Mojo::Promise object resolving to the return value of the callback if
117       it is called, or to its original fulfillment value if the promise is
118       instead fulfilled.
119
120         # Longer version
121         my $new = $promise->then(undef, sub {...});
122
123         # Pass along the rejection reason
124         $promise->catch(sub {
125           my @reason = @_;
126           warn "Something went wrong: $reason[0]";
127           return @reason;
128         });
129
130         # Change the rejection reason
131         $promise->catch(sub {
132           my @reason = @_;
133           return "This is bad: $reason[0]";
134         });
135
136   clone
137         my $new = $promise->clone;
138
139       Return a new Mojo::Promise object cloned from this promise that is
140       still pending.
141
142   finally
143         my $new = $promise->finally(sub {...});
144
145       Appends a fulfillment and rejection handler to the promise, and returns
146       a new Mojo::Promise object resolving to the original fulfillment value
147       or rejection reason.
148
149         # Do something on fulfillment and rejection
150         $promise->finally(sub {
151           say "We are done!";
152         });
153
154   map
155         my $new = Mojo::Promise->map(sub {...}, @items);
156         my $new = Mojo::Promise->map({concurrency => 3}, sub {...}, @items);
157
158       Apply a function that returns a Mojo::Promise to each item in a list of
159       items while optionally limiting concurrency. Returns a Mojo::Promise
160       that collects the results in the same manner as "all". If any item's
161       promise is rejected, any remaining items which have not yet been mapped
162       will not be. Note that this method is EXPERIMENTAL and might change
163       without warning!
164
165         # Perform 3 requests at a time concurrently
166         Mojo::Promise->map({concurrency => 3}, sub { $ua->get_p($_) }, @urls)
167           ->then(sub{ say $_->[0]->res->dom->at('title')->text for @_ });
168
169       These options are currently available:
170
171       concurrency
172           concurrency => 3
173
174         The maximum number of items that are in progress at the same time.
175
176   new
177         my $promise = Mojo::Promise->new;
178         my $promise = Mojo::Promise->new(sub {...});
179
180       Construct a new Mojo::Promise object.
181
182         # Wrap a continuation-passing style API
183         my $promise = Mojo::Promise->new(sub {
184           my ($resolve, $reject) = @_;
185           Mojo::IOLoop->timer(5 => sub {
186             if (int rand 2) { $resolve->('Lucky!') }
187             else            { $reject->('Unlucky!') }
188           });
189         });
190
191   race
192         my $new = Mojo::Promise->race(@promises);
193
194       Returns a new Mojo::Promise object that fulfills or rejects as soon as
195       one of the passed Mojo::Promise objects fulfills or rejects, with the
196       value or reason from that promise.
197
198   reject
199         my $new  = Mojo::Promise->reject(@reason);
200         $promise = $promise->reject(@reason);
201
202       Build rejected Mojo::Promise object or reject the promise with one or
203       more rejection reasons.
204
205         # Longer version
206         my $promise = Mojo::Promise->new->reject(@reason);
207
208   resolve
209         my $new  = Mojo::Promise->resolve(@value);
210         $promise = $promise->resolve(@value);
211
212       Build resolved Mojo::Promise object or resolve the promise with one or
213       more fulfillment values.
214
215         # Longer version
216         my $promise = Mojo::Promise->new->resolve(@value);
217
218   then
219         my $new = $promise->then(sub {...});
220         my $new = $promise->then(sub {...}, sub {...});
221         my $new = $promise->then(undef, sub {...});
222
223       Appends fulfillment and rejection handlers to the promise, and returns
224       a new Mojo::Promise object resolving to the return value of the called
225       handler.
226
227         # Pass along the fulfillment value or rejection reason
228         $promise->then(
229           sub {
230             my @value = @_;
231             say "The result is $value[0]";
232             return @value;
233           },
234           sub {
235             my @reason = @_;
236             warn "Something went wrong: $reason[0]";
237             return @reason;
238           }
239         );
240
241         # Change the fulfillment value or rejection reason
242         $promise->then(
243           sub {
244             my @value = @_;
245             return "This is good: $value[0]";
246           },
247           sub {
248             my @reason = @_;
249             return "This is bad: $reason[0]";
250           }
251         );
252
253   timer
254         my $new  = Mojo::Promise->timer(5 => 'Success!');
255         $promise = $promise->timer(5 => 'Success!');
256         $promise = $promise->timer(5);
257
258       Create a new Mojo::Promise object with a timer or attach a timer to an
259       existing promise. The promise will be resolved after the given amount
260       of time in seconds with or without a value. Note that this method is
261       EXPERIMENTAL and might change without warning!
262
263   timeout
264         my $new  = Mojo::Promise->timeout(5 => 'Timeout!');
265         $promise = $promise->timeout(5 => 'Timeout!');
266         $promise = $promise->timeout(5);
267
268       Create a new Mojo::Promise object with a timeout or attach a timeout to
269       an existing promise. The promise will be rejected after the given
270       amount of time in seconds with a reason, which defaults to "Promise
271       timeout". Note that this method is EXPERIMENTAL and might change
272       without warning!
273
274   wait
275         $promise->wait;
276
277       Start "ioloop" and stop it again once the promise has been fulfilled or
278       rejected, does nothing when "ioloop" is already running.
279

SEE ALSO

281       Mojolicious, Mojolicious::Guides, <https://mojolicious.org>.
282
283
284
285perl v5.30.0                      2019-07-26                  Mojo::Promise(3)
Impressum