Promise domains are used to temporarily set up custom environments that
intercept and influence the registration of callbacks. Create new promise
domain objects using new_promise_domain
, and temporarily activate a promise
domain object (for the duration of evaluating a given expression) using
with_promise_domain
.
Usage
with_promise_domain(domain, expr, replace = FALSE)
new_promise_domain(
wrapOnFulfilled = identity,
wrapOnRejected = identity,
wrapSync = force,
onError = force,
...,
wrapOnFinally = NULL
)
Arguments
- domain
A promise domain object to install while
expr
is evaluated.- expr
Any R expression, to be evaluated under the influence of
domain
.- replace
If
FALSE
, then the effect of thedomain
will be added to the effect of any currently active promise domain(s). IfTRUE
, then the current promise domain(s) will be ignored for the duration of thewith_promise_domain
call.- wrapOnFulfilled
A function that takes a single argument: a function that was passed as an
onFulfilled
argument tothen()
. ThewrapOnFulfilled
function should return a function that is suitable foronFulfilled
duty.- wrapOnRejected
A function that takes a single argument: a function that was passed as an
onRejected
argument tothen()
. ThewrapOnRejected
function should return a function that is suitable foronRejected
duty.- wrapSync
A function that takes a single argument: a (lazily evaluated) expression that the function should
force()
. This expression represents theexpr
argument passed towith_promise_domain()
;wrapSync
allows the domain to manipulate the environment before/afterexpr
is evaluated.- onError
A function that takes a single argument: an error.
onError
will be called whenever an exception occurs in a domain (that isn't caught by atryCatch
). Providing anonError
callback doesn't cause errors to be caught, necessarily; instead,onError
callbacks behave like calling handlers.- ...
Arbitrary named values that will become elements of the promise domain object, and can be accessed as items in an environment (i.e. using
[[
or$
).- wrapOnFinally
A function that takes a single argument: a function that was passed as an
onFinally
argument tothen()
. ThewrapOnFinally
function should return a function that is suitable foronFinally
duty. IfwrapOnFinally
isNULL
(the default), then the domain will use bothwrapOnFulfilled
andwrapOnRejected
to wrap theonFinally
. If it's important to distinguish between normal fulfillment/rejection handlers and finally handlers, then be sure to providewrapOnFinally
, even if it's justbase::identity()
.
Details
While with_promise_domain
is on the call stack, any calls to then()
(or
higher level functions or operators, like catch()
or the various pipes)
will belong to the promise domain. In addition, when a then
callback that
belongs to a promise domain is invoked, then any new calls to then
will
also belong to that promise domain. In other words, a promise domain
"infects" not only the immediate calls to then
, but also to "nested" calls
to then
.
For more background, read the original design doc.
For examples, see the source code of the Shiny package, which uses promise domains extensively to manage graphics devices and reactivity.