【问题标题】:Implement typing delay in ScalaJS?在 ScalaJS 中实现输入延迟?
【发布时间】:2018-03-23 05:59:01
【问题描述】:

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

我尝试将等效的 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

【问题讨论】:

  • 我已经编辑了原始问题以展示我尝试过的内容

标签: scala.js timedelay


【解决方案1】:

您的代码中的问题是您将() => 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) {}

【讨论】:

  • 太好了,解决了!谢谢你的解释
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-23
  • 1970-01-01
相关资源
最近更新 更多