Liking cljdoc? Tell your friends :D

jtk-dvlp.async

Drop-in replacements for core.async that propagate errors.

In plain core.async an exception thrown inside a go block is swallowed: the block's channel just closes and the caller sees nil. Here the exception travels as a value on the channel and is thrown again by <! in whichever go block takes it. Inside a go that throw is caught once more and becomes that block's result — so an error keeps climbing the go block stack until someone catches it, the way it would in synchronous code.

Stack traces are stitched across the boundary, so a trace shows both the block that failed and the one that asked for the value. See athrow.

Everything in this namespace propagates errors that way, and an exception travels as itself: the class, message and ex-data that were thrown are the ones caught. Only a thrown value that is no exception at all — which ClojureScript allows — is lifted into an ExceptionInfo carrying {:code :unknown, :error x}.

WATCHOUT: Do not mix these with clojure.core.async. Propagation only works because the error is an ordinary value on the channel — a plain core.async/<! in between takes that value silently, and the error is gone with nothing left to notice it by.

Drop-in replacements for `core.async` that propagate errors.

In plain `core.async` an exception thrown inside a `go` block is
swallowed: the block's channel just closes and the caller sees
`nil`. Here the exception travels as a *value* on the channel and is
thrown again by `<!` in whichever go block takes it. Inside a `go`
that throw is caught once more and becomes that block's result — so
an error keeps climbing the go block stack until someone catches it,
the way it would in synchronous code.

Stack traces are stitched across the boundary, so a trace shows both
the block that failed and the one that asked for the value. See
`athrow`.

Everything in this namespace propagates errors that way, and an
exception travels as itself: the class, message and `ex-data` that
were thrown are the ones caught. Only a thrown value that is no
exception at all — which ClojureScript allows — is lifted into an
`ExceptionInfo` carrying `{:code :unknown, :error x}`.

WATCHOUT: Do not mix these with `clojure.core.async`. Propagation
only works because the error is an ordinary value on the channel — a
plain `core.async/<!` in between takes that value silently, and the
error is gone with nothing left to notice it by.
raw docstring

jtk-dvlp.async.interop.callback

Turns callback-based functions into channels, with the error propagation of jtk-dvlp.async.

A callback API does not fit into a sequence of steps: the rest of the work has to move inside the callback, and every further call nests one level deeper. cb->c turns such a call into a channel, so it reads like any other step in a go block — and a failure arrives as a thrown error rather than as a second callback.

WATCHOUT: cb->c is a macro that rewrites the expression handed to it. It looks for the symbols callback, resolve and reject inside and puts its own functions in their place. Those symbols are therefore written bare, without ever being defined — and they are only found where they literally stand. Move a callback into a helper function and the macro cannot see it any more.

Turns callback-based functions into channels, with the error
propagation of `jtk-dvlp.async`.

A callback API does not fit into a sequence of steps: the rest of
the work has to move inside the callback, and every further call
nests one level deeper. `cb->c` turns such a call into a channel, so
it reads like any other step in a go block — and a failure arrives
as a thrown error rather than as a second callback.

WATCHOUT: `cb->c` is a macro that *rewrites* the expression handed
to it. It looks for the symbols `callback`, `resolve` and `reject`
inside and puts its own functions in their place. Those symbols are
therefore written bare, without ever being defined — and they are
only found where they literally stand. Move a callback into a helper
function and the macro cannot see it any more.
raw docstring

jtk-dvlp.async.interop.promise

Bridges promises and channels, in both directions, with the error propagation of jtk-dvlp.async.

A rejected promise arrives on the channel as a carried error and is thrown by <!; an error carried on a channel rejects the promise it is turned into. So a .then/.catch chain and a go block stack can be mixed without either side losing an error.

WATCHOUT: promise means different things on the two platforms. In ClojureScript it is a js/Promise with then and catch. On the JVM it is a clojure.core/promise, which has neither and only takes a single deliver — there is no rejection there, only a delivered exception value. The functions here even that out; where it still shows through, it is said so.

Bridges promises and channels, in both directions, with the error
propagation of `jtk-dvlp.async`.

A rejected promise arrives on the channel as a carried error and is
thrown by `<!`; an error carried on a channel rejects the promise it
is turned into. So a `.then`/`.catch` chain and a go block stack can
be mixed without either side losing an error.

WATCHOUT: `promise` means different things on the two platforms. In
ClojureScript it is a `js/Promise` with `then` and `catch`. On the
JVM it is a `clojure.core/promise`, which has neither and only takes
a single `deliver` — there is no rejection there, only a delivered
exception value. The functions here even that out; where it still
shows through, it is said so.
raw docstring

jtk-dvlp.async.print

Prints what a channel ends up with — the value, or the error it carries.

For looking at a channel at the REPL. Printing a go channel directly shows the channel object, and a plain println on its value would show a carried error as an inert map rather than as the failure it is. These take the value out with jtk-dvlp.async/<!, so an error shows up as an error.

Debug aids, not logging: they print, they do not report.

Prints what a channel ends up with — the value, or the error it
carries.

For looking at a channel at the REPL. Printing a `go` channel
directly shows the channel object, and a plain `println` on its
value would show a carried error as an inert map rather than as the
failure it is. These take the value out with `jtk-dvlp.async/<!`, so
an error shows up as an error.

Debug aids, not logging: they print, they do not report.
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close