在 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) {}
我在 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) {}