Is there no standard function for this, turning a channel into a js promise? https://stackoverflow.com/questions/69198810/how-to-return-a-promise-from-a-go-block
a promise either resolves or rejects once. a channel is a fundamentally different thing, so no there is no generic translation since you kinda need to be specific for behavior you want exactly
In this case my channel behaves pretty much like a promise, producing a result once it's done
sounds like a promise-chan. https://clojure.github.io/core.async/clojure.core.async.html#var-promise-chan However, this is not a direct answer to your question 😞
There's no such function built into CLJS.
(defn take-once [chan]
(js/Promise.
(fn [resolve _]
(async/take! chan
(fn [val]
(resolve val))))))something like that. take-once from the channel in form of a promise
could just be (async/take! chan resolve) but being a bit more verbose might make it easier to see what is going on 😛
but there are many things to consider, like taking from a closed channel or promises that never deliver .. the list is long
called it take-once because thats clearer in its intent that just chan->promise or so, kinda up to you 🤷
Couldn't resist.
So... a go block returns a channel that receives the result right. I basically want to check the go block is "done"
You don't need a promise for that.
You can just use take! and pass a callback.
Okay rephrase, I want some piece of JS code that expects an async function to "wait" until the go block is done
we have an interop namespace in core.async, and we have helpers for going from promise to chan, but not the other way around. happy to take a patch for that. the docstring should be extra clear about the behavior.
and what is that JS code calling exactly? does it call into CLJS code directly? does it have a reference to the channel directy? if it has access to the result of take-once when await just works
(defn some-fn-called-from-js [] (take-once (go 1)))
const val = await some_fn_called_from_js(); will have val 1
Yea I think your take once will work
opaque errors ahead...
SES_UNCAUGHT_EXCEPTION: TypeError: c is undefined
cljs$core$async$impl$ioc_helpers$take_BANG_ ioc_helpers.cljs:53
switch__11740__auto__ filestore.cljs:36
ret_value__11742__auto__ filestore.cljs:36
nyancad$mosaic$filestore$read_file_$_state_machine__11741__auto____1 nyancad.mosaic.filestore.js:112
cljs$core$async$impl$ioc_helpers$run_state_machine ioc_helpers.cljs:43
cljs$core$async$impl$ioc_helpers$run_state_machine_wrapped ioc_helpers.cljs:47
read_file filestore.cljs:36
cljs$core$async$impl$dispatch$process_messages dispatch.cljs:27
onmessage nexttick.js:195
getNextTickImpl_ nexttick.js:189
nextTick nexttick.js:59
cljs$core$async$impl$dispatch$queue_dispatcher dispatch.cljs:37
cljs$core$async$impl$dispatch$run dispatch.cljs:41
nyancad$hipflask$get_group hipflask.cljs:53
cljs$core$IFn$_invoke$arity$3 hipflask.cljs:149
<anonymous> filestore.cljs:17
globalEval common.js:455
evalLoad common.js:1426
<anonymous> filestore.js:1
lockdown-install.js:1:138390It seems "take!" takes a third (optional?) argument called c which.. does that correspond to on-caller?
the error points here:
(defn take! [state blk ^not-native c]
(if-let [cb (impl/take! c (fn-handler <<<<<<<
(fn [x]
(ioc/aset-all! state VALUE-IDX x STATE-IDX blk)
(run-state-machine-wrapped state))))]
(do (ioc/aset-all! state VALUE-IDX @cb STATE-IDX blk)
:recur)
nil))thats the wrong place to be looking. 100% certain what you are just passing nil into something that shouldn't be nil
like (take! nil (fn ...))
guessing filestore.cljs line 36 😉
take! has 2 arities, so the on-caller? arg isn't relevant (and defaults to true)
yeah I did something silly, just... not very easy to see inside a go block
yeah, kind of the reason I never use core.async in CLJS
I mean async debugging is never easy, but go is just madness