首页 > 解决方案 > 如何在 Immutable.js 中序列化数据历史以启用时间旅行?

问题描述

对于我正在处理的 TypeScript/JavaScript 项目,我需要某种具有完全持久性的支持时间旅行的数据结构。该数据结构需要能够序列化到数据库或至少是文件系统。我希望能够分支旧版本进行修改,但我不需要像合并分支那样做任何花哨的事情。我想我需要某种 HAMT(https://en.wikipedia.org/wiki/Hash_array_mapped_trie) 例如在 Immutable.js 中实现的。然而,我还需要将内部结构保存到数据库或磁盘的能力。大多数人在区分数据结构时使用 Immutable.js,例如在确定是否更新 React 组件时,这是一个非常有用的属性。然而,我需要的是时间旅行和序列化,以便有效地存储节点并保留所有历史记录。这两件事都是 HAMT 的属性,但是 Immutable.js 似乎不支持这一点。也许我在文档中遗漏了一些东西。Immutable.js 有可能吗?如果没有,是否有人知道我可以用来完成此任务的任何库?我必须实施自己的 HAMT 吗?


更新:

要清楚,我需要序列化内部数据结构而不是它的表示。据我所知,这意味着我需要某种哈希表来跟踪每个节点。当我们谈论持久数据结构时,我只想序列化新节点,因为它们是在突变时写入的,我不想序列化整个数据树或它的表示。

我知道我可以简单地从 Immutable.js 获取任何操作的输出并保存该数据的序列化副本,就好像我在 Redux 中使用它和 Redux Dev Tools 一样。问题是这会在网络上产生过多的流量并导致我们的数据存储需求爆炸,这不是我在这种情况下真正需要的。

标签: javascriptimmutable.jstrie

解决方案


这里有两个问题。

如何在 Immutable.js 中利用时间旅行?

Immutable.js 本身并没有实现时间旅行,但是库的数据结构的性质(任何修改都会返回对数据“快照”的新引用)使得自己很容易实现。您需要做的就是在数据结构上创建一个“历史容器”或包装器,它会自动将 Immutable 创建的每个新引用存储在映射中。然后您将能够撤消/重做,并在地图上搜索特定时间。在 Google Books 上 Adam Boduch 的这本书的免费预览中,有一个使用代理的示例实现。当然,您可以根据需要对其进行修改。

如何在 Immutable.js 中序列化数据?

JavaScript 中事实上的序列化技术是toJSON(). Immutable.js 实现toJSON()了它提供的每个数据结构。从自述文件

所有 Immutable.js 集合都可以使用 toArray() 和 toObject() 浅层转换为纯 JavaScript 数组和对象,或者使用 toJS() 深层转换。所有不可变集合也实现了 toJSON() 允许它们直接传递给 JSON.stringify。他们还尊重嵌套对象的自定义 toJSON() 方法。

JSON.parse(data)您可以通过反序列化并将其传递给构造函数或在任何不可变结构中使用,将 JSON 转换回不可.fromJS()变结构。


推荐阅读