manifold.deferred
Methods for creating, transforming, and interacting with asynchronous values.
->deferred
(->deferred x)
(->deferred x default-val)
Transforms x
into a deferred if possible, or returns default-val
. If no default value is given, an IllegalArgumentException
is thrown.
add-listener!
(add-listener! deferred listener)
Registers a listener which can be cancelled via cancel-listener!
. Unless this is useful, prefer on-realized
.
alt
(alt & vals)
Takes a list of values, some of which may be deferrable, and returns a deferred that will yield the value which was realized first.
@(alt 1 2) => 1 @(alt (future (Thread/sleep 1) 1) (future (Thread/sleep 1) 2)) => 1 or 2 depending on the thread scheduling
Values appearing earlier in the input are preferred.
cancel-listener!
(cancel-listener! deferred listener)
Cancels a listener which has been registered via add-listener!
.
catch
(catch x error-handler)
(catch x error-class error-handler)
An equivalent of the catch clause, which takes an error-handler
function that will be invoked with the exception, and whose return value will be yielded as a successful outcome. If an error-class
is specified, only exceptions of that type will be caught. If not, all exceptions will be caught.
(-> d
(chain f g h)
(catch IOException #(str "oh no, IO: " (.getMessage %)))
(catch #(str "something unexpected: " (.getMessage %))))
catch'
(catch' x error-handler)
(catch' x error-class error-handler)
Like catch
, but does not coerce deferrable values.
chain
(chain x)
(chain x f)
(chain x f g)
(chain x f g & fs)
Composes functions, left to right, over the value x
, returning a deferred containing the result. When composing, either x
or the returned values may be values which can be converted to a deferred, causing the composition to be paused.
The returned deferred will only be realized once all functions have been applied and their return values realized.
@(chain 1 inc #(future (inc %))) => 3
@(chain (future 1) inc inc) => 3
chain'
(chain' x)
(chain' x f)
(chain' x f g)
(chain' x f g & fs)
Like chain
, but does not coerce deferrable values. This is useful both when coercion is undesired, or for 2-4x better performance than chain
.
claim!
(claim! deferred)
Attempts to claim the deferred for future updates. If successful, a claim token is returned, otherwise returns nil
.
deferrable?
(deferrable? x)
Returns true if the object can be coerced to a Manifold deferred.
deferred
(deferred)
(deferred executor)
Equivalent to Clojure’s promise
, but also allows asynchronous callbacks to be registered and composed via chain
.
error!
(error! deferred x)
(error! deferred x claim-token)
Puts the deferred into an error state.
error-deferred
(error-deferred error)
(error-deferred error executor)
A deferred which already contains a realized error
finally
(finally x f)
An equivalent of the finally clause, which takes a no-arg side-effecting function that executes no matter what the result.
future
macro
(future & body)
Equivalent to Clojure’s future
, but returns a Manifold deferred.
future-with
macro
(future-with executor & body)
Equivalent to Clojure’s future
, but allows specification of the executor and returns a Manifold deferred.
let-flow
macro
(let-flow bindings & body)
A version of let
where deferred values that are let-bound or closed over can be treated as if they are realized values. The body will only be executed once all of the let-bound values, even ones only used for side effects, have been computed.
Returns a deferred value, representing the value returned by the body.
(let-flow [x (future 1)] (+ x 1))
(let-flow [x (future 1) y (future (+ x 1))] (+ y 1))
(let [x (future 1)] (let-flow [y (future (+ x 1))] (+ y 1)))
listener
(listener on-success)
(listener on-success on-error)
Creates a listener which can be registered or cancelled via add-listener!
and cancel-listener!
.
loop
macro
(loop bindings & body)
A version of Clojure’s loop which allows for asynchronous loops, via manifold.deferred/recur
. loop
will always return a deferred value, even if the body is synchronous. Note that loop
does not coerce values to deferreds, actual Manifold deferreds must be used.
(loop [i 1e6] (chain (future i) #(if (zero? %) % (recur (dec %)))))
on-realized
(on-realized x on-success on-error)
Registers callbacks with the manifold deferred for both success and error outcomes.
success!
(success! deferred x)
(success! deferred x claim-token)
Equivalent to deliver
, but allows a claim-token
to be passed in.
success-deferred
(success-deferred val)
(success-deferred val executor)
A deferred which already contains a realized value
timeout!
(timeout! d interval)
(timeout! d interval timeout-value)
Takes a deferred, and sets a timeout on it, such that it will be realized as timeout-value
(or a TimeoutException if none is specified) if it is not realized in interval
ms. Returns the deferred that was passed in.
This will act directly on the deferred value passed in. If the deferred represents a value returned by chain
, all actions not yet completed will be short-circuited upon timeout.
zip
(zip & vals)
Takes a list of values, some of which may be deferrable, and returns a deferred that will yield a list of realized values.
@(zip 1 2 3) => [1 2 3]
@(zip (future 1) 2 3) => [1 2 3]