在ScalaJS中实现输入延迟?

时间:2018-03-20 14:51:13

标签: scala.js timedelay

我在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

1 个答案:

答案 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]