Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 持久数据结构如何帮助提高Om速度_Clojure_Clojurescript_Om - Fatal编程技术网

Clojure 持久数据结构如何帮助提高Om速度

Clojure 持久数据结构如何帮助提高Om速度,clojure,clojurescript,om,Clojure,Clojurescript,Om,React的clojurescript包装器Om据说速度非常快,因为它利用了不变性。我不明白持久数据结构在这里有什么帮助 我所理解的是,应用程序状态是一个原子。此状态被传递给返回虚拟DOM节点的函数(om组件),因此创建当前虚拟DOM与其先前状态之间差异的“补丁”比直接在实际DOM上操作要好得多 但是持久性数据结构在哪里有帮助呢? (def app-state (atom {:foo {:counter 0})) (om/root click-counter app-state {:target

React的clojurescript包装器Om据说速度非常快,因为它利用了不变性。我不明白持久数据结构在这里有什么帮助

我所理解的是,应用程序状态是一个原子。此状态被传递给返回虚拟DOM节点的函数(om组件),因此创建当前虚拟DOM与其先前状态之间差异的“补丁”比直接在实际DOM上操作要好得多

但是持久性数据结构在哪里有帮助呢?

(def app-state (atom {:foo {:counter 0}))
(om/root click-counter app-state {:target ...}) 
例如,
单击计数器
呈现一个按钮,单击该按钮时计数器会递增。因此,转换函数如下所示:

(dom/button #js {:onClick #(om/transact! app [:foo :counter] inc)} 
            (str "clicked " (-> app :foo :counter) " times"))
{:foo {:counter 1}}
{:part1 [1 2 3 4]
 :part2 [:a :b]}
我不理解这一点:当执行
onClick
时,clojurescript会创建一个新的映射(非常有效),如下所示:

(dom/button #js {:onClick #(om/transact! app [:foo :counter] inc)} 
            (str "clicked " (-> app :foo :counter) " times"))
{:foo {:counter 1}}
{:part1 [1 2 3 4]
 :part2 [:a :b]}
appstate
现在指向新地图。在这一点上,Om意识到状态已经改变,因为这只是一个等式检查的问题

这里的问题是,Om仍然应该计算整个旧虚拟DOM和新虚拟DOM之间的差异。它不知道只是换了计数器


我的错误在哪里?

当应用程序状态存储在一个持久的树结构(如地图)中时,很明显状态树的哪些部分没有更改,也不需要更新。这是因为对子对象的任何更改都会更改父对象。对于可变数据结构,对子对象的更改不必更改父对象

所以如果你所在的州是这样的:

(dom/button #js {:onClick #(om/transact! app [:foo :counter] inc)} 
            (str "clicked " (-> app :foo :counter) " times"))
{:foo {:counter 1}}
{:part1 [1 2 3 4]
 :part2 [:a :b]}
您可以通过在第2部分中添加一些内容来创建一个新状态:

{:part1 [1 2 3 4]
 :part2 [:a :b :c]}

然后,比较函数可以查看新旧状态的:part1中的值是完全相同的对象,因此不能对任何嵌套状态进行任何更改,因为它是不可变的。

谢谢。因此,只有当节点上的相等性检查失败时,才需要对其子节点进行最终重新呈现。如果相等性失败,则可能需要重新呈现,尽管可能不需要,但您可以更改它,然后将其更改回去。如果相等性通过,那么您绝对不需要更新它。我看到的问题是,对于大平面数据结构,例如由数千个元素组成的向量(可能是类似excel的应用程序),您只需更改向量的一个元素:
(def cells(atom(into[](replicate 1000{:val:empty}))
,然后
(swap!(单元格[1:val]10中的assoc))
。这会导致Om检查所有元素,因为数据结构的根已更改,并且您不知道哪个单元格已被修改。因此,考虑到Om不能很好地处理大平面数据结构,似乎所有内容都完全取决于您决定如何构造应用程序状态。