简体   繁体   中英

Using an anonymous Js function in a go block

I'm attempting to do some timed animation in clojurescript/reagent and I'm trying to use core.async to achieve series of timed steps in order. I'm using a third party js react library, so, to call its functions I'm using the form (fn [] ^js (.function (.something @ref)). However putting this anonymous function inside the go block as follows doesn't work -

(go
   (js/console.log "going")
   (<! (timeout 3000))
   (fn [] ^js (.function (.somedata @lib))
   (js/console.log "landed")
           )

This returns "going" and "landed" timed correctly and works when putting another console.log function in its place. However if you wrap this console.log in an Fn it no longer gets called. It is being called in the:on-click handler of a component. What have I missed?

That ^js there is unnecessary.

When you wrap something in (fn []...) , that something is not called unless that fn is called. Ie ((fn []...)) . But then, you end up creating a function and calling it immediately, which is completely unnecessary.

So, assuming I understand you correctly, you can simply replace that (fn [] ^js...) with (-> @lib.somedata.function) .

On a side note, somedata sounds like it's just a field that has some data and not a function that needs to be called. If that's the case, use .-somedata instead of .somedata .

As mentioned by Eugene Pakhomov using (fn []...) only creates a function, it does not call it. Thus it it basically just elimnated entirely without doing anything.

Your motiviation here seems to get rid of the inference warning. So the underlying problem is that core.async is rather forgetful when in comes to type hints. If you ask me you shouldn't do any interop in go blocks at all and rather move it all out. Either via defn or local function outside the go .

(defn do-something []
  (.function (.somedata ^js @lib)))

(go
   (js/console.log "going")
   (<! (timeout 3000))
   (do-something)   
   (js/console.log "landed"))
(let [do-something (fn [] (.function (.somedata ^js @lib)))]
  (go
     (js/console.log "going")
     (<! (timeout 3000))
     (do-something)   
     (js/console.log "landed")))

Also, just a word of caution. Using core.async for this will substantially increase the amount of code generated for code in go blocks. If you really need to do is delay something use (js/setTimeout do-something 3000) . Use go with caution, it'll easily generate 10x the code for some things than would normally be required.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM