在 ScalaJS 中实现打字延迟?

Implement typing delay in ScalaJS?

我在 ScalaJS 应用程序中有一个搜索输入字段,它会在用户输入城市名称时触发对后端服务器的请求。但是,我需要实施延迟,以便在一定的延迟(比如 1000 毫秒)之后才会触发请求。如果没有这样的延迟,我有可能在搜索中得到误报(例如,如果用户想要搜索 "paris",那么 "par" 就会出现误报 - a英国康沃尔小镇-输入第三个字符时)

我试过将 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 的参数,这也提供了一个视觉线索,即它是 by-name参数:

(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) {}