Angular 服务,实时将缓存数组中的 observables/subjects 返回到组件的多个实例 [英] Angular service that returns observables/subjects from a cache array to multiple instances of a component in realtime

查看:22
本文介绍了Angular 服务,实时将缓存数组中的 observables/subjects 返回到组件的多个实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

用例

我有一个包含多个 UserActionsComponent 实例的内容页面.我还有一个全局 DataService,它充当具有(想要的)高级缓存的数据提供者.

I have a content page that has multiple instances of UserActionsComponent. I also have a global DataService that acts as a data provider with (wannabe) advanced caching.

数据获取层次:

内存缓存 >> 浏览器存储(异步)>> HTTP 请求

UserActionsComponent

请求 dataService.getData(URL,params,method)

PS:params 有像 blogId 这样的细节,这使得哈希签名是唯一的

PS: params has details like blogId which makes the hash signature unique

数据服务 (.getData())

1) 使用诸如 genUniqueHash(URL+stringify(params)+method) 之类的方法创建唯一的哈希 KEY

1) Makes a unique hash KEY using something like genUniqueHash(URL+stringify(params)+method)

2) 检查内存缓存 (array[KEY]) 中是否存在值 - 如果是,则返回 ob$

2) Checks if value is present in an in-memory cache (array[KEY]) - If yes, return ob$

3) 检查浏览器存储中是否存在值(异步;使用 Ionic 存储) - 如果是,则返回 ob$ else - 保存到内存缓存,然后返回 ob$(array[KEY])

3) Check if value is present in browser's storage (async; uses Ionic storage) - If yes, return ob$ else - save to in-memory cache, then return ob$(array[KEY])

4) 从 HTTP Call 中获取值,保存到 Storage,保存到内存缓存并返回 ob$(array[KEY])

4) Get the value from HTTP Call, save to Storage, save to in-memory cache and return ob$(array[KEY])

这个概念不起作用,因为我无法弄清楚如何从缓存值数组中返回一个共享的 observable(我猜这应该是一个 BehaviourSubject?).请带我走上正轨.

This concept is not working as I am not able to figure out how to return a shared observable (I'm guessing this should be a BehaviourSubject?) from an array of cache values. Please bring me on the right track.

注意事项

  • 如果用户对一个组件投了赞成票,它必须反映在视图中的所有其他实例(该特定博客条目的所有 UserActionsComponent 都应更新)
  • 同一页面上的一个视图中可以有多个 UserActionsComponent(例如:对于 BlogEntry#1 和 BlogEntry#25)!
  • 内存缓存随着用户访问新的博客帖子而不断增长(这很好,因为它是一个有限集)

我是 RxJS 的菜鸟.我试了一下运气:

I'm a noob to RxJS. I tried my luck with:

  • pipe(share()) [因为它是一个服务,所以管道与所有 URL 共享]
  • 返回 of(cache[key]) [不起作用,因为最后获取的 BlogEntry 的用户操作会反映在所有订阅中]
  • 返回整个缓存,然后在 UserActionsComponent 端过滤掉所需的数据(使用数组[KEY])(这是当前的实现)

当前的实现有效,但对于这个用例来说,它似乎不是最好的方法.原因是:一个视图可能有多达 20 个 UAC [UAC-A(1), UAC-B(1), UAC(200) ...].UAC 发出 next() 两次.UAC 的 onInit 以及用户在 UAC 中投赞成票或反对票时.现在,由于发生更改,我们发出缓存数据,因此此页面视图会发出 2*20 次大小为 20 的数组.

The current implementation works, but it doesn't seem the best way to do it for this use case. Reason being: One view might have up-to 20 UACs [UAC-A(1), UAC-B(1), UAC(200) ...]. UAC emits next() twice. onInit of UAC and when user up-votes or down-votes in a UAC. Now since on change, we emit the cache data, an array of size 20 is emitted 2*20 times for this page view.

使用 RxJS 实现这一点的最优化方法是什么?

What would be the most optimized way to implement this using RxJS?

推荐答案

当前实现:

把它写下来,因为它对未来的某人有帮助.我设法以这种方式使用可观察模式对其进行优化:

Writing it down as it would be helpful for someone in the future. I managed to optimize it using observable pattern this way:

  • UAC onInit() 调用 dataService.getData(url,params,method,guid)
  • UAC传递的guid是服务的缓存key
  • UAC 有两个来自 dataService 的订阅.一个是 dataService.getData 方法,它返回一个 observable - 主要用作设置 guid 的初始化器 - 它在使用 .pipe(first()) 获取其第一个值后取消订阅.第二个订阅是对名为 dataChanged 的​​ BehaviourSubject.每当 dataService 缓存上的数据发生更改时,它都会发出 dataChanged.next(newDataDelta).此订阅持续到组件的 onDestroy.
  • dataService 按cache[guid] > 分层检查存储[指南] >http[url],相应地设置数据,最后调用dataChangedSubj.next(cache[guid]) 只发出变化的delta
  • 所有 UAC 接收新的缓存数据集(即 cache[guid];仅包含更改的内容)并检查 receivedData[guid] 以查看发出的数据是否与 UAC 相关.如果是,它会消耗它.
  • 如果用户对 UAC 投赞成票/反对票,UAC 会执行必要的 API 调用,如果成功,会调用 dataService.updateData(guid,data),后者又会使用 dataChanged.next 发出更改(newDataDelta) 到所有 UAC,属于同一博客文章的 UAC 将更新其数据(因为它们将具有相同的 guid)
  • UAC onInit() calls dataService.getData(url,params,method,guid)
  • The guid passed by the UAC is the cache key for the service
  • UAC has two subscriptions from dataService. One is dataService.getData method that returns an observable - mainly used as an initializer to set guid - it unsubscribes after getting its first value using .pipe(first()). Second subscription is to a BehaviourSubject called dataChanged. Whenever data is changed on dataService cache, it emits dataChanged.next(newDataDelta). This subscription persists till the component's onDestroy.
  • dataService checks hierarchically as cache[guid] > storage[guid] > http[url], sets data accordingly, and finally calls dataChangedSubj.next(cache[guid]) Only the changed delta would be emitted
  • All UACs receive the new cached DataSet (which is cache[guid]; contains only what was changed) and checks for receivedData[guid] to see if the emitted data is relevant to the UAC. If yes, it consumes it.
  • If user up-votes/down-votes on a UAC, UAC does necessary API calls, and on success, does dataService.updateData(guid,data), which in-turn emits the change using dataChanged.next(newDataDelta) to all UACs and the UACs that belong to the same blog post would update its data (as they would have the same guid)

对于使用 RxJS 实现此用例的最佳方式仍然开放.

Still open for the best way to implement this use case using RxJS.

这篇关于Angular 服务,实时将缓存数组中的 observables/subjects 返回到组件的多个实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆