简体   繁体   English

在 go 块中使用匿名 Js function

[英]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.我正在尝试在 clojurescript/reagent 中执行一些定时 animation 并且我正在尝试使用 core.async 来按顺序实现一系列定时步骤。 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 -我正在使用第三方 js 反应库,因此,调用它的函数我使用的形式是 (fn [] ^js (.function (.something @ref))。但是将这个匿名 function 放在 go 块中以下不起作用 -

(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.这会正确计时返回“going”和“landed”,并且在放置另一个 console.log function 时可以正常工作。 However if you wrap this console.log in an Fn it no longer gets called.但是,如果您将此 console.log 包装在 Fn 中,它将不再被调用。 It is being called in the:on-click handler of a component.它在组件的:on-click 处理程序中被调用。 What have I missed?我错过了什么?

That ^js there is unnecessary.那个^js是没有必要的。

When you wrap something in (fn []...) , that something is not called unless that fn is called.当您将某些内容包装在(fn []...)中时,除非调用fn ,否则不会调用该内容。 Ie ((fn []...)) .((fn []...)) But then, you end up creating a function and calling it immediately, which is completely unnecessary.但是,您最终创建了一个 function 并立即调用它,这是完全没有必要的。

So, assuming I understand you correctly, you can simply replace that (fn [] ^js...) with (-> @lib.somedata.function) .因此,假设我理解正确,您可以简单地将(fn [] ^js...)替换为(-> @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.在旁注中, somedata听起来只是一个包含一些数据的字段,而不是需要调用的 function。 If that's the case, use .-somedata instead of .somedata .如果是这种情况,请使用.-somedata而不是.somedata

As mentioned by Eugene Pakhomov using (fn []...) only creates a function, it does not call it.正如 Eugene Pakhomov 所提到的,使用(fn []...)只会创建一个 function,它不会调用它。 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.所以潜在的问题是core.async在输入提示时相当健忘。 If you ask me you shouldn't do any interop in go blocks at all and rather move it all out.如果您问我,您根本不应该在go块中进行任何互操作,而是将其全部移出。 Either via defn or local function outside the go .通过defn或本地 function 在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.为此使用 core.async 将大大增加为go块中的代码生成的代码量。 If you really need to do is delay something use (js/setTimeout do-something 3000) .如果你真的需要做的是延迟使用(js/setTimeout do-something 3000) Use go with caution, it'll easily generate 10x the code for some things than would normally be required.谨慎使用go ,它很容易为某些事情生成比通常需要的代码多 10 倍的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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