在 go 块中使用匿名 Js 函数

问题描述 投票:0回答:2

我正在尝试在 clojurescript/reagent 中做一些定时动画,并且我正在尝试使用 core.async 来按顺序实现一系列定时步骤。我正在使用第三方 js React 库,因此,要调用它的函数,我使用的是 (fn [] ^js (.function (.something @ref)) 形式。但是,将此匿名函数放入 go 块中,如下所示以下不起作用 -

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

这将返回正确计时的“going”和“landed”,并且在将另一个 console.log 函数放在其位置时起作用。但是,如果您将此 console.log 包装在 Fn 中,它将不再被调用。它在组件的 :on-click 处理程序中被调用。我错过了什么?

clojurescript reagent core.async
2个回答
2
投票

那个

^js
没有必要。

当您将某些内容包裹在

(fn [] ...)
中时,除非调用
fn
,否则不会调用该内容。 IE。
((fn [] ...))
。但是,您最终会创建一个函数并立即调用它,这是完全没有必要的。

所以,假设我理解正确,您可以简单地将

(fn [] ^js ...)
替换为
(-> @lib .somedata .function)

顺便说一句,

somedata
听起来像是一个包含一些数据的字段,而不是需要调用的函数。如果是这种情况,请使用
.-somedata
而不是
.somedata


1
投票

正如 Eugene Pakhomov 所提到的,使用

(fn [] ...)
只创建一个函数,而不调用它。因此它基本上只是完全消除而不做任何事情。

你在这里的动机似乎摆脱了推理警告。所以根本的问题是

core.async
在输入提示时相当健忘。如果你问我,你根本不应该在
go
块中进行任何互操作,而应该将其全部移出。通过
defn
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")))

另外,请注意一点。为此使用 core.async 将大大增加为

go
块中的代码生成的代码量。如果您确实需要延迟某些事情,请使用
(js/setTimeout do-something 3000)
。谨慎使用
go
,它很容易为某些事情生成比通常需要的代码多 10 倍的代码。

© www.soinside.com 2019 - 2024. All rights reserved.