|
| 1 | +<p><a href="psi_element://Future%3A%3AAsyncAwait">Future::AsyncAwait</a>: <a href="psi_element://Future%3A%3AAsyncAwait%2FDESCRIPTION">DESCRIPTION</a></p><h2><code>await</code></h2><p style="padding-bottom: 10px;">The <code>await</code> keyword forms an expression which takes a <code>Future</code> instance as |
| 2 | +an operand and yields the eventual result of it. Superficially it can be |
| 3 | +thought of similar to invoking the <code>get</code> method on the future.</p> |
| 4 | +<div style="padding-bottom: 10px;"><pre><code> my $result = await $f; |
| 5 | + |
| 6 | + my $result = $f->get;</code></pre></div> |
| 7 | +<p style="padding-bottom: 10px;">However, the key difference (and indeed the entire reason for being a new |
| 8 | +syntax keyword) is the behaviour when the future is still pending and is not |
| 9 | +yet complete. Whereas the simple <code>get</code> method would block until the future is |
| 10 | +complete, the <code>await</code> keyword causes its entire containing function to become |
| 11 | +suspended, making it return a new (pending) future instance. It waits in this |
| 12 | +state until the future it was waiting on completes, at which point it wakes up |
| 13 | +and resumes execution from the point of the <code>await</code> expression. When the |
| 14 | +now-resumed function eventually finishes (either by returning a value or |
| 15 | +throwing an exception), this value is set as the result of the future it had |
| 16 | +returned earlier.</p> |
| 17 | +<p style="padding-bottom: 10px;"><code>await</code> provides scalar context to its controlling expression.</p> |
| 18 | +<div style="padding-bottom: 10px;"><pre><code> async sub func { |
| 19 | + # this function is invoked in scalar context |
| 20 | + } |
| 21 | + |
| 22 | + await func();</code></pre></div> |
| 23 | +<p style="padding-bottom: 10px;">Because the <code>await</code> keyword may cause its containing function to suspend |
| 24 | +early, returning a pending future instance, it is only allowed inside |
| 25 | +<code>async</code>-marked subs.</p> |
| 26 | +<p style="padding-bottom: 10px;">The converse is not true; just because a function is marked as <code>async</code> does |
| 27 | +not require it to make use of the <code>await</code> expression. It is still useful to |
| 28 | +turn the result of that function into a future, entirely without <code>await</code>ing |
| 29 | +on any itself.</p> |
| 30 | +<p style="padding-bottom: 10px;">Any function that doesn't actually await anything, and just returns immediate |
| 31 | +futures can be neatened by this module too.</p> |
| 32 | +<p style="padding-bottom: 10px;">Instead of writing</p> |
| 33 | +<div style="padding-bottom: 10px;"><pre><code> sub imm |
| 34 | + { |
| 35 | + ... |
| 36 | + return Future->done( @result ); |
| 37 | + }</code></pre></div> |
| 38 | +<p style="padding-bottom: 10px;">you can now simply write</p> |
| 39 | +<div style="padding-bottom: 10px;"><pre><code> async sub imm |
| 40 | + { |
| 41 | + ... |
| 42 | + return @result; |
| 43 | + }</code></pre></div> |
| 44 | +<p style="padding-bottom: 10px;">with the added side-benefit that any exceptions thrown by the elided code will |
| 45 | +be turned into an immediate-failed <code>Future</code> rather than making the call |
| 46 | +itself propagate the exception, which is usually what you wanted when dealing |
| 47 | +with futures.</p> |
0 commit comments