如何将Redux与非常大的数据集和IndexedDB集成

时间:2015-11-30 06:41:05

标签: javascript redux

我有一个使用同步API来获取其数据的应用,并且需要在本地存储所有数据。 数据集本身非常大,我不愿意将它存储在内存中,因为它可以包含数千条记录。由于我不认为实际的数据结构是相关的,我们假设我正在构建一个需要离线访问的电子邮件客户端,并且我希望我的存储机制是IndexedDB(这是异步的)。

我知道一个简单的解决方案是不将数据结构作为我的状态对象的一部分,并且仅使用所需数据填充状态(例如,当触发EMAIL_OPEN操作时,将电子邮件内容存储在状态中)。这很简单,特别是对于redux-thunk。

然而,这意味着我需要妥协两件事:

  1. 用户数据不再是“应用程序状态”的一部分,尽管事实确实如此。由于同步行为很复杂,将其从app状态机中删除会损害redux概念的优雅(我理解它们的方式)
  2. 我非常喜欢redux架构,并希望我的所有逻辑都能通过它,而不仅仅是视图状态。
  3. 是否有关于如何将redux与非内存状态属性一起使用的最佳实践?我发现最难解决的问题是redux依赖于同步API,因此我无法用异步状态对象替换我的状态对象(除非我完全删除redux并将其替换为我自己的异步实现和连接器)。

    我找不到使用谷歌的答案,但如果有关于这个主题的资源已经很好,我也很乐意指出。

    更新: 问题得到了回答,但是想要更好地解释我是如何实现它的,以防有人碰到它:

    主要思想是使用简单的redux reducer维护客户端和服务器的更改列表,并使用连接器监听这些更改列表以更新IDB,并使用客户端更改来更新服务器:

    1. 当客户端进行更改时,请使用reducers更新客户端更改列表。
    2. 当服务器发送更新时,使用reducers更新服务器更改列表。
    3. 连接器侦听存储,并在状态更改时更新IDB。还要维护已修改的项目的内部列表。
    4. 更新服务器时,使用已修改项目列表从IDB拉取增量并发送到服务器。
    5. 访问数据时,使用常规操作从IDB中提取(例如使用redux-thunk)
    6. 这种方法唯一需要注意的是,由于真实状态存储在IDB中,所以我们确实失去了一个状态对象的价值(并且更难以倒带/快进状态)

1 个答案:

答案 0 :(得分:23)

我认为你的第一次预感是正确的。如果(!)您无法在商店中存储所有商品,则必须在商店中存储更少的商品。但我相信我能让这个解决方案听起来更好:

IndexedDB只是成为另一个端点,就像您使用的任何服务器API一样。从服务器获取数据时,将其转发到IndexedDB,然后从中填充商店。只要它不会变得太大或陈旧,商店就可以获得它所需要的东西并进行缓存。

与Facebook消费他们的API真的没什么不同。从来没有商店中用户的所有数据。引用使用ID实现,并在需要时加载。

您可以将所有逻辑保留在redux中。只需像往常一样为用户操作和数据更改创建操作,获取所需的数据并进行处理。该界面仍然完全由用户数据定义,因为您始终拥有商店中需要的信息,以便在需要时获取其余部分。它有点浓缩,我。即您只保存邮件总数或邮箱ID,直到用户导航到该邮箱。