EVOLUTION-MANAGER
Edit File: then.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>R: Access the results of a promise</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link rel="stylesheet" type="text/css" href="R.css" /> </head><body> <table width="100%" summary="page for then {promises}"><tr><td>then {promises}</td><td style="text-align: right;">R Documentation</td></tr></table> <h2>Access the results of a promise</h2> <h3>Description</h3> <p>Use the <code>then</code> function to access the eventual result of a promise (or, if the operation fails, the reason for that failure). Regardless of the state of the promise, the call to <code>then</code> is non-blocking, that is, it returns immediately; so what it does <em>not</em> do is immediately return the result value of the promise. Instead, you pass logic you want to execute to <code>then</code>, in the form of function callbacks (or formulas, see Details). If you provide an <code>onFulfilled</code> callback, it will be called upon the promise's successful resolution, with a single argument <code>value</code>: the result value. If you provide an <code>onRejected</code> callback, it will be called if the operation fails, with a single argument <code>reason</code>: the error that caused the failure. </p> <h3>Usage</h3> <pre> then(promise, onFulfilled = NULL, onRejected = NULL) catch(promise, onRejected, tee = FALSE) finally(promise, onFinally) </pre> <h3>Arguments</h3> <table summary="R argblock"> <tr valign="top"><td><code>promise</code></td> <td> <p>A promise object. The object can be in any state.</p> </td></tr> <tr valign="top"><td><code>onFulfilled</code></td> <td> <p>A function (or a formula–see Details) that will be invoked if the promise value successfully resolves. When invoked, the function will be called with a single argument: the resolved value. Optionally, the function can take a second parameter <code>.visible</code> if you care whether the promise was resolved with a visible or invisible value. The function can return a value or a promise object, or can throw an error; these will affect the resolution of the promise object that is returned by <code>then()</code>.</p> </td></tr> <tr valign="top"><td><code>onRejected</code></td> <td> <p>A function taking the argument <code>error</code> (or a formula–see Details). The function can return a value or a promise object, or can throw an error. If <code>onRejected</code> is provided and doesn't throw an error (or return a promise that fails) then this is the async equivalent of catching an error.</p> </td></tr> <tr valign="top"><td><code>tee</code></td> <td> <p>If <code>TRUE</code>, ignore the return value of the callback, and use the original value instead. This is useful for performing operations with side-effects, particularly logging to the console or a file. If the callback itself throws an error, and <code>tee</code> is <code>TRUE</code>, that error will still be used to fulfill the the returned promise (in other words, <code>tee</code> only has an effect if the callback does not throw).</p> </td></tr> <tr valign="top"><td><code>onFinally</code></td> <td> <p>A function with no arguments, to be called when the async operation either succeeds or fails. Usually used for freeing resources that were used during async operations.</p> </td></tr> </table> <h3>Formulas</h3> <p>For convenience, the <code>then()</code>, <code>catch()</code>, and <code>finally()</code> functions use <code><a href="../../rlang/html/as_function.html">rlang::as_function()</a></code> to convert <code>onFulfilled</code>, <code>onRejected</code>, and <code>onFinally</code> arguments to functions. This means that you can use formulas to create very compact anonymous functions, using <code>.</code> to access the value (in the case of <code>onFulfilled</code>) or error (in the case of <code>onRejected</code>). </p> <h3>Chaining promises</h3> <p>The first parameter of <code>then</code> is a promise; given the stated purpose of the function, this should be no surprise. However, what may be surprising is that the return value of <code>then</code> is also a (newly created) promise. This new promise waits for the original promise to be fulfilled or rejected, and for <code>onFulfilled</code> or <code>onRejected</code> to be called. The result of (or error raised by) calling <code>onFulfilled</code>/<code>onRejected</code> will be used to fulfill (reject) the new promise.</p> <pre>promise_a <- get_data_frame_async() promise_b <- then(promise_a, onFulfilled = head) </pre> <p>In this example, assuming <code>get_data_frame_async</code> returns a promise that eventually resolves to a data frame, <code>promise_b</code> will eventually resolve to the first 10 or fewer rows of that data frame. </p> <p>Note that the new promise is considered fulfilled or rejected based on whether <code>onFulfilled</code>/<code>onRejected</code> returns a value or throws an error, not on whether the original promise was fulfilled or rejected. In other words, it's possible to turn failure to success and success to failure. Consider this example, where we expect <code>some_async_operation</code> to fail, and want to consider it an error if it doesn't:</p> <pre>promise_c <- some_async_operation() promise_d <- then(promise_c, onFulfilled = function(value) { stop("That's strange, the operation didn't fail!") }, onRejected = function(reason) { # Great, the operation failed as expected NULL } ) </pre> <p>Now, <code>promise_d</code> will be rejected if <code>promise_c</code> is fulfilled, and vice versa. </p> <p><strong>Warning:</strong> Be very careful not to accidentally turn failure into success, if your error handling code is not the last item in a chain!</p> <pre>some_async_operation() %>% catch(function(reason) { warning("An error occurred: ", reason) }) %>% then(function() { message("I guess we succeeded...?") # No! }) </pre> <p>In this example, the <code>catch</code> callback does not itself throw an error, so the subsequent <code>then</code> call will consider its promise fulfilled! </p> <h3>Convenience functions</h3> <p>For readability and convenience, we provide <code>catch</code> and <code>finally</code> functions. </p> <p>The <code>catch</code> function is equivalent to <code>then</code>, but without the <code>onFulfilled</code> argument. It is typically used at the end of a promise chain to perform error handling/logging. </p> <p>The <code>finally</code> function is similar to <code>then</code>, but takes a single no-argument function (or formula) that will be executed upon completion of the promise, regardless of whether the result is success or failure. It is typically used at the end of a promise chain to perform cleanup tasks, like closing file handles or database connections. Unlike <code>then</code> and <code>catch</code>, the return value of <code>finally</code> is ignored; however, if an error is thrown in <code>finally</code>, that error will be propagated forward into the returned promise. </p> <h3>Visibility</h3> <p><code>onFulfilled</code> functions can optionally have a second parameter <code>visible</code>, which will be <code>FALSE</code> if the result value is <a href="../../base/html/invisible.html">invisible</a>. </p> <hr /><div style="text-align: center;">[Package <em>promises</em> version 1.1.1 <a href="00Index.html">Index</a>]</div> </body></html>