如何在Elm中实现setTimeout行为
我正在用Elm写一个网络游戏,里面有很多与时间相关的事件,我正在寻找一种方法来安排一个特定时间延迟的事件 在JavaScript中,我使用了如何在Elm中实现setTimeout行为,elm,Elm,我正在用Elm写一个网络游戏,里面有很多与时间相关的事件,我正在寻找一种方法来安排一个特定时间延迟的事件 在JavaScript中,我使用了setTimeout(f,timeout),这显然效果很好,但出于各种原因,我希望避免使用JavaScript代码,而只使用Elm 我知道我可以在特定的时间间隔订阅Tick,并接收时钟信号,但这不是我想要的-我的延迟没有合理的公分母(例如,其中两个延迟为30ms和500ms),我希望避免处理大量不必要的信号 我还遇到了Task和Process——似乎通过使用
setTimeout(f,timeout)
,这显然效果很好,但出于各种原因,我希望避免使用JavaScript代码,而只使用Elm
我知道我可以在特定的时间间隔订阅Tick
,并接收时钟信号,但这不是我想要的-我的延迟没有合理的公分母(例如,其中两个延迟为30ms和500ms),我希望避免处理大量不必要的信号
我还遇到了Task
和Process
——似乎通过使用它们,我能够以某种方式实现我对Task.perform failHandler successHandler(Process.sleep Time.second)
的要求
这是可行的,但不是很直观——我的处理程序只是忽略所有可能的输入并发送相同的消息。此外,我并不期望超时会失败,因此创建失败处理程序感觉就像是给库提供信息,这不是我从如此优雅的语言中所期望的
是否有类似于
Task.delayMessage time message
的功能可以完全满足我的需要(在指定的时间后向我发送其消息参数的副本),或者我必须为其制作自己的包装器?一开始可能不明显的一点是,订阅可以根据模型进行更改。每次更新后都会对其进行有效评估。您可以使用这个事实,再加上模型中的一些字段,来控制什么订阅在任何时候都处于活动状态
下面是一个示例,它允许:
订阅:模型->子消息
订阅模式=
如果model.showCursor
然后是Time.every model.cursorBlinkInterval(始终切换光标)
其他子项无
如果我理解您的担忧,这将克服处理不必要的滴答声的可能性。通过使用
Sub.batch
可以拥有不同时间间隔的多个订阅。如果您希望“每x秒”发生一次事件,则您需要@ChadGilbert所描述的类似订阅的解决方案。(这或多或少类似于javascript的setInterval()
)
另一方面,如果您只希望某件事情“在x秒后发生一次”,那么进程.睡眠
路径就是要走的路。这相当于javascript的设置超时()
:经过一段时间后,它会做一次事情
你可能需要自己做包装,比如
-- for Elm 0.18
delay : Time -> msg -> Cmd msg
delay time msg =
Process.sleep time
|> Task.andThen (always <| Task.succeed msg)
|> Task.perform identity
——用于Elm 0.18
延迟:时间->消息->命令消息
延迟时间=
睡眠时间
|>Task.and然后(始终为Task.perform identity
使用,例如这样:
---
update msg model =
case msg of
NewStuff somethingNew ->
...
Defer somethingNew ->
model
! [ delay (Time.second * 5) <| NewStuff somethingNew ]
---
更新msg模型=
味精案例
NewStuff somethingNew->
...
延迟一些新内容->
模型
![delay(Time.second*5)的更新和简化版本现在是:
使用相同的用法时Elm 0.19:
要执行一次并延迟:
delay : Float -> msg -> Cmd msg
delay time msg =
Process.sleep time
|> Task.andThen (always <| Task.succeed msg)
|> Task.perform identity
仅供参考,elm lang/core在任务方面似乎有点不同。请执行。请参阅@Tosh。事实上,它似乎刚刚得到更新,以支持无故障情况。是否有办法在超时过期之前取消延迟的操作?一种方法是“取消”是在模型中设置一个标志,然后在最终消息的情况下检查该标志(NewStuff
在上述情况下)编辑:不太有状态的是将模型传递给NewStuff
,然后对照当前模型进行检查,如果它们不同,则取消。除了取消消息,我同意以不同的方式处理它。并且在SomethingNew
分支内建立检查,以确定是否仍然需要生成包含消息的新模型。标记In model是最符合逻辑的。您的update
函数已经可以访问该模型,无需在消息中传递它。理由:严格来说,您的Elm代码无法控制发送给update
函数的消息流。因此update
函数应该假设消息可以在任何时间以某种方式传入ny order.@Grav您能给我指一些文档或示例代码,它们与您所描述的内容相符吗?谢谢!我用什么来代替时间呢?时间
似乎不再起作用了?它的第一个参数是浮点
。
delay : Float -> msg -> Cmd msg
delay time msg =
Process.sleep time
|> Task.andThen (always <| Task.succeed msg)
|> Task.perform identity
every : Float -> (Posix -> msg) -> Sub msg