我在ScalaJS应用程序中有一个搜索输入字段,用于在用户输入城市名称时触发对后端服务器的请求。但是,我需要实现一个延迟,以便在一定延迟(比如1000ms)之后才会触发请求。如果没有这样的延迟,我有机会在搜索中找回误报(如果用户想搜索“巴黎”,那么“par”将会出现误报 - 康沃尔郡的一个小镇,英格兰 - 当输入第三个字符时)
我尝试将JavaScript等价物转录到Scala中,但是setTimeout部分似乎不起作用。
import scala.scalajs.js.timers.{SetTimeoutHandle, clearTimeout, setTimeout}
private def delay = () => {
// Set initial timeout to do nothing after 0 ms
var handle: SetTimeoutHandle = setTimeout(0)(() => {})
(fn: Function0[Unit], ms: Double) => {
clearTimeout(handle)
handle = setTimeout(ms)(fn)
}
}
然后我正在使用Akka Actor
处理用户输入事件def receive = {
/************************************************
* Client event
* The user has typed something into the search field
*/
case evt: Event =>
delay()(handleInput, 1000.0)
}
其中handleInput
是零参数函数,它获取用户的输入,然后向后端发出请求。
执行清除然后重置超时的匿名内部函数,但不会调用handleInput函数
由于
Chris W
答案 0 :(得分:2)
您的代码中的问题是您向setTimeout
提供setTimeout
类型的函数,但是setTimeout
takes a by-name parameter。换句话说,val result = fn // result is the *function* itself, but does not call it
的参数应该是超时到期时要执行的语句。如果你给它一个函数,那么在超时后该函数值将被评估,但该函数将不被调用!
类似于错误地尝试
val result = fn() // fn is called, result is what it returns
而不是
setTimeout
您可以通过fn
替换fn()
来将来电固定到{}
。此外,在这些情况下,使用()
代替setTimeout
作为(fn: Function0[Unit], ms: Double) => {
clearTimeout(handle)
handle = setTimeout(ms) {
fn()
}
}
的参数通常更为惯用,这也提供了一个视觉线索,即它是一个名字参数:
setTimeout
你也应该调整你的第一个虚拟// Set initial timeout to do nothing after 0 ms
var handle: SetTimeoutHandle = setTimeout(0) {}
以保持一致性,尽管因为它无论如何都是假的,这不会改变行为:
In [132]: df['new_col'] = np.take(df.columns, np.argsort(df)).tolist()
In [133]: df
Out[133]:
A B C new_col
0 3 1 2 [B, C, A]
1 2 1 3 [B, A, C]
2 3 2 1 [C, B, A]