我在 ScalaJS 应用程序中有一个搜索输入字段,当用户输入城市名称时,它会向后端服务器发出请求。但是,我需要实现一个延迟,以便在一定延迟(例如 1000 毫秒)之后才触发请求。如果没有这样的延迟,我就有可能在搜索中得到误报(例如,如果用户想要搜索“paris”,那么就会出现错误的“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函数
谢谢
克里斯W
最佳答案
代码中的问题是您将 () => Unit
类型的函数赋予 setTimeout
,但是 setTimeout
takes a by-name parameter 。换句话说,setTimeout
的参数应该是超时到期时执行的语句。如果你给它一个函数,那么在超时后,该函数值将被评估,但该函数将不会被调用!
这类似于错误地尝试这样做
val result = fn // result is the *function* itself, but does not call it
而不是
val result = fn() // fn is called, result is what it returns
您可以通过将 fn
替换为 fn()
来修复对 setTimeout
的调用。此外,在这种情况下,通常更惯用的做法是使用 {}
而不是 ()
作为 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) {}
关于scala.js - 在 ScalaJS 中实现输入延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49387411/