Changelog
Source:NEWS.md
promises 1.4.0
Breaking changes
- Nested promise domains now correctly invoke in reverse order. Previously, when promise domains were nested, the outer domain would incorrectly take precedence over the inner domain in
wrapOnFulfilled
/wrapOnRejected
callbacks. The innermost (most recently added) domain now properly wraps the callback first, ensuring that nested promise domains behave consistently with the expected scoping behavior. (#165)
New features
hybrid_then()
synchronously or asynchronously executes success/failure callbacks based on whether the input is a promise or a regular value. This function is useful for writing code that can handle both synchronous and asynchronous inputs seamlessly. (#192)then()
gains atee
parameter. Whentee = TRUE
,then()
ignores the return value of the callback and returns the original value instead. This is useful for performing operations with side-effects, particularly logging to the console or a file.finally()
does not supporttee
as the return value is always ignored. (#148)
OpenTelemetry integration
promises now integrates with the otel package to provide observability and tracing for asynchronous operations. OpenTelemetry integration is experimental and subject to change.
with_ospan_async()
creates an OpenTelemetry span, executes the given expression within it, and ends the span. This function handles both synchronous and asynchronous (promise-based) operations. For promises, the span is automatically ended when the promise resolves or rejects. To access the OpenTelemetry span within your expression, useotel::get_current_span()
. (#173)with_ospan_promise_domain()
creates a promise domain that restores the currently active OpenTelemetry span from when a call tothen()
is executed. This enables proper tracing context across asynchronous operations. (#173)local_ospan_promise_domain()
adds an OpenTelemetry span promise domain to the local scope. This is useful for coro operations where encapsulating the coro operations insidewith_*()
methods is not allowed. (#179)
Minor improvements and fixes
promises now requires R 4.1 or later. R’s native pipe (
|>
) and function shorthand (\(x) fn(x)
) syntax are now preferred over promise pipe methods. The promise pipe methods (%...>%
,%...!%
,%...T>%
) are now superseded in favor of the R syntax supported in R 4.1 or later. (#148)catch()
API updated fromcatch(promise, onRejected, tee = FALSE)
tocatch(promise, onRejected, ..., tee = FALSE)
. Thetee
parameter must now be specified as a keyword argument. (#148)then(tee=)
andcatch(tee=)
now require a logical value (not just a truthy value). (#156)promises is now a pure R package that does not require compilation. We include a test of a C++ interface in
inst/promise_task.cpp
that is now dynamically compiled during testing. (#154)promise_all()
performance improved by using a counter instead of checking completion status of all promises. This changes the time complexity fromO(n^2)
toO(n)
for determining when all promises are complete. (#163)promise_all()
now preserves duplicate named arguments (or.list
entries). A result will be produced for every promise provided. (#163)promise_map()
now properly handlesNULL
values being returned. (Thank you, @RLesur! #47)promises no longer imports base packages in DESCRIPTION. (Thank you, @shikokuchuo! #186)
promises 1.3.3
CRAN release: 2025-05-29
Changed the way we create future objects to stay compatible with new versions of future. Apparently the way we were doing it was never idiomatic and only worked by accident. (#121)
Fixed #122: Use
future::future(..., lazy = TRUE)
to avoid manual capturing of state withinfuture_promise
(Thank you, @HenrikBengtsson! #123)
promises 1.3.2
CRAN release: 2024-11-27
- Fixed bug introduced in 1.3.1, where promise domains that are active at promise resolution time stay active during handler callback, even if they weren’t active when the handler was registered. This was causing stack overflow for long promise chains with many active promise domains. (#115)
promises 1.3.1
CRAN release: 2024-11-26
- Fixed bug where promise domains were forgotten when handlers were registered from within other handlers. (#110)
promises 1.2.1
CRAN release: 2023-08-10
future_promise()
received a speed improvement when submitting many requests with a minimal number of future workers. Iffuture_promise()
runs out of available future workers, thenfuture_promise()
will preemptively return for the remainder of the current later execution. While it is possible for future to finish a job before submitting all of thefuture_promise()
requests, the time saved by not asking future’s worker availability will be faster overall than if a few jobs were submitted early. (#78)Fixed #86:
future_promise()
spuriously reports unhandled errors. (#90)Move fastmap from
Suggests
toImports
for better renv discovery. (#87)
promises 1.2.0.1
CRAN release: 2021-02-11
Added
future_promise()
which returns apromise
that executes the expression usingfuture::future()
.future_promise()
should (typically) be a drop-in replacement for anyfuture::future()
function call.future_promise()
will not executefuture
work faster thanfuture::future()
, butfuture_promise()
will only submitfuture
jobs if a worker is available. If no workers are available,future_promise()
will hold the expression information in apromise
until a worker does become available to better take advantage of computing resources available to the main R session. For more information, please see thefuture_promise()
article. (#62)Added visibility support for
Promise$then(onFulfilled)
. (#59)
promises 1.1.1
CRAN release: 2020-06-09
- Fix handling of FutureErrors during
future::resolved()
andfuture::value()
by discarding the corrupt future. (#37)
promises 1.1.0
CRAN release: 2019-10-04
Fixed #49:
promise_all()
previously did not handleNULL
values correctly. (#50)new_promise_domain
now takes awrapOnFinally
argument, which can be used to intercept registration offinally()
. Previous versions treatedfinally
as passing the same callback tothen(onFulfilled=..., onRejected=...)
, and ignoring the result; for backward compatibility, promise domains will still treatfinally
that way by default (i.e. ifwrapOnFinally
isNULL
, thenfinally
will result inwrapOnFulfilled
andwrapOnRejected
being called, but ifwrapOnFinally
is provided then onlywrapOnFinally
will be called). (#43)