我是ELM的新手,我正试图把我的头绕在异步计算上。
我正在尝试编写一个ELM程序来自动生成放射学报告。该程序使用图形数据结构来存储切换、无线电和编辑框的分层树的状态,用户可以编辑(添加、删除、移动)切换。单个开关也可以修改其行为,以便打开一个开关,将显示或隐藏其他开关。例如,当您切换Chest时ON,肺肝会被隐藏起来。我通过在update
函数中使用图形的边缘来做到这一点,然后在view
函数中进行解释和渲染。然后我用各种各样的查表计算出对应于一组特定的英语短语或切换,像肝脏,囊肿,3,mm,segment_4.这工作得很好,但是计算英语短语的计算成本很高,并且它阻塞了我的UI线程。
我一直在玩Tasks
和Process.swap
,但不知何故我误解了他们。我认为我可以改变我的ToggleOnOff
消息实现,这样我就可以产生长时间运行的实现,立即返回我的新状态(即,(model, Cmd msg)),并设置生成的处理,以便在计算完成时再次使用英文文本字符串调用更新。
我有一个generateReport
函数,我用Task.succeed
变成了一个任务。然后我试图生成这个generateReportTask
,并使用Task.andThen
将其链接到msgUpdateReportFullText
。然后,在长时间运行的generateReportTask
运行并自行调用update以将英文文本添加到模型之前,我需要立即返回一个具有切换状态的新模型。
我相信我仍然在思考这个问题,我误解了FP和ELM。我使用ELM的经验总是告诉我,ELM的方式总是比我笨拙的命令式的新手尝试更短、更清晰。
谁能教育我,帮助一个可怜的家伙看到光明?谢谢你!(抱歉的干燥没有代码的问题,但我的程序很难在几行再现…)
长时间运行的计算在web平台上是有点棘手的,特别是如果你希望它们不阻塞用户界面。
实际上你有两个选择:
-
使用Web Workers. 这是一种技术,它实际上可以启动一个新进程,该进程可以与UI进程完全并行运行。不幸的是,Web Workers基本上是一个完全独立的程序,它通过(大部分)序列化消息与主程序通信。这意味着你执行的计算必须比序列化/反序列化的最终成本更快。
在Elm中,您将使用
Platform.worker
程序,然后在JavaScript中添加端口并将它们连接在一起。这篇文章似乎对此做了一些详细的描述。 -
你可以把你的计算分成小块,每帧执行一个小块。在某些情况下,这甚至可以更好地工作,其中存在可以渲染的中间结果,尽管这不是必需的。您可以看到我在这里写的一个示例(注意它实际上是如何花费几秒钟来计算图形的布局的,但它看起来只是一个整洁的小动画)。