promises 1.5.0
CRAN release: 2025-11-01
OpenTelemetry
promises now integrates with the otel package to provide observability and tracing for asynchronous operations.
local_otel_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)with_otel_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)with_otel_span()creates an OpenTelemetry span, executes the given expression within it, and ends the span when the expression completes. 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(). (#198)
New features
- Promises are now simple classed environments rather than R6 classes. This reduces their creation overhead by up to 10x, thereby substantially improving performance. (#191)
Life cycle changes
-
local_ospan_promise_domain(),with_ospan_async(), andwith_ospan_promise_domain()are deprecated in favor oflocal_otel_promise_domain(),with_otel_span(), andwith_otel_promise_domain()respectively. (#198)
promises 1.4.0
CRAN release: 2025-10-22
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/wrapOnRejectedcallbacks. 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 ateeparameter. 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 supportteeas 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). Theteeparameter 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.cppthat 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.listentries). A result will be produced for every promise provided. (#163)promise_map()now properly handlesNULLvalues 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
SuggeststoImportsfor better renv discovery. (#87)
promises 1.2.0.1
CRAN release: 2021-02-11
Added
future_promise()which returns apromisethat executes the expression usingfuture::future().future_promise()should (typically) be a drop-in replacement for anyfuture::future()function call.future_promise()will not executefuturework faster thanfuture::future(), butfuture_promise()will only submitfuturejobs if a worker is available. If no workers are available,future_promise()will hold the expression information in apromiseuntil 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 handleNULLvalues correctly. (#50)new_promise_domainnow takes awrapOnFinallyargument, which can be used to intercept registration offinally(). Previous versions treatedfinallyas passing the same callback tothen(onFulfilled=..., onRejected=...), and ignoring the result; for backward compatibility, promise domains will still treatfinallythat way by default (i.e. ifwrapOnFinallyisNULL, thenfinallywill result inwrapOnFulfilledandwrapOnRejectedbeing called, but ifwrapOnFinallyis provided then onlywrapOnFinallywill be called). (#43)