【问题标题】:RxJS - Keep a cache of the list and update the existing onesRxJS - 保留列表的缓存并更新现有的
【发布时间】:2021-06-04 14:38:20
【问题描述】:

我有一个 WebSocket 连接,它做两件事:

  • 在第一个 'DATA' 事件上发送完整列表(即:5 个项目)
  • 在每个下一个“DATA”中,它只发送有关更新的信息。

我想获取该流,对其进行处理,保留项目缓存并执行以下操作:

  • 保留现有列表。
  • 如果有新事件到达并在列表中,则根据 id 更新它(这应该足够通用)。
  • 如果不存在,请将其添加到列表中。

这是我到目前为止所做的。这并不多。我每次都在附加项目。任何帮助将不胜感激:

function createCachedList$<T extends WSMessage<T>>(observable$: Observable<T>) {
  const INITIAL_STATE: any[] = [];

  const [fromDataPackets$, fromNonDataPackets$] = partition(
    observable$,
    (value) => value.type === WSMessageType.DATA
  );

  const pickDataPacket = fromDataPackets$.pipe(
    map((value: any) => value?.data),
    scan((prevState, currState: any[]) => {
      const nextState = R.uniq([...prevState, ...currState]);
      return [...prevState, ...nextState];
    }, INITIAL_STATE),
    tap((data: any) => console.log('Data:', data)),
    map((data: any) => ({ type: WSMessageType.DATA, data }))
  );

  return merge(pickDataPacket, fromNonDataPackets$);
}

export default createCachedList$;

【问题讨论】:

    标签: javascript typescript websocket rxjs


    【解决方案1】:

    您的代码似乎没问题。 scan 是我将使用的运算符。

    您可能需要详细说明scan 中的逻辑。这样的事情可能会有所帮助

    scan((prevState, currState: any[]) => {
      currState.forEach(m => {
        const item = prevState.find(s => s.id === m.id);
        if (item) {
           Object.assign(item, m)
        } else {
           prevState.push(m)
        }
      });
      return prevState;
    }, INITIAL_STATE),
    

    【讨论】:

    • 我会接受您的回答,因为它使我得出了正确的结论。我遇到的问题基本上是将结果包装在另一个数组中,第二个原因是对象只是嵌套的,并没有全部复制。不得不使用华美达 deepMergeRight 来做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 2018-02-14
    相关资源
    最近更新 更多