angular - RxJS 的某种待办事项列表
问题描述
我目前在一个角度项目中使用 RxJS。在这个项目中,我有一个应该作为待办事项列表的列表:
- 一开始,列表中包含 5 个项目。
- 用户可以删除一个元素。
- 当一个元素被移除时,一个新元素被获取。
- 当列表为空时,将获取新元素。
我设法使用 3 个 observables 和 1 个状态来做到这一点:
// api.fetchElement -> ({ count: number, exclude: string[] }) => Observable<Element[]>
// removedElements$ -> Subject<string>
let elements = []
const initialElements$ = api.fetchElement({ count: 5 })
// removedElementId$ is a subject of string
// in which element ids are produced.
const reloadedElements$ = removedElementId$.pipe(
// My API is eventualy consistent, so I need to exclude the removed items
// for a short period.
mergeMap(id => api.fetchElement({ count: 5, exclude: [ id ] })
)
const reloadedElementsWhenEmptyList$ = interval(3000).pipe(
filter(() => elements.length < 5),
mergeMap(() => api.fetchElement({ count: 5 - elements.length, exclude: elements.map(e => e.id) })
)
initialElements$.subscribe({
next: newElements => elements = newElements
})
reloadedElements$.subscribe({
next: newElements => elements = newElements
})
reloadedElementsWhenEmptyList$.subscribe({
next: newElements => elements = newElements
})
当前的实现有效,但我想知道是否有一种方法可以执行相同的行为,但不必elements
在可观察运算符中使用最终状态?
我在 RxJS 文档中搜索了运算符,但我没有找到任何满足我需要的运算符或运算符组合。
解决方案
您的设置有点奇怪,我不禁想知道是否有更好的方法来构建它。可悲的是,这里没有足够的知识。
无论哪种方式,您都可以elements
通过创建一个在订阅时发出最新elements
数组的 observable 来摆脱全局状态。在这个示例实现中,我称它为elements$
const initialElements$ = api.fetchElement({ count: 5 });
// removedElementId$ is a subject of string
// in which element ids are produced.
const reloadedElements$ = removedElementId$.pipe(
// My API is eventualy consistent, so I need to exclude the removed items
// for a short period.
mergeMap(id => api.fetchElement({
count: 5,
exclude: [ id ]
}))
);
const reloadedElementsWhenEmptyList$ = interval(3000).pipe(
switchMap(_ => elements$),
filter(elements => elements.length < 5),
mergeMap(elements => api.fetchElement({
count: 5 - elements.length,
exclude: elements.map(e => e.id)
}))
);
const elements$ = merge(
initialElements$,
reloadedElements$,
reloadedElementsWhenEmptyList$
).pipe(
startWith([]),
shareReplay(1)
);
您会注意到,当我需要访问您的旧元素数组时,我只是订阅了elements$
.
如果您使用的是 TypeScript,可能需要做一些额外的工作来确保您的类型在此处对齐。同样,您的示例中没有足够的信息来执行此操作,但我会将这个练习留给您。
推荐阅读
- selenium-webdriver - 如何使用 python 解决 selenium 的分页问题-flipkart.com
- python - Django 错误 - ImportError:无法从“first_project”导入名称“first_app”
- computer-vision - 人脸识别:种族属性
- python - 如何定位缩略图 discord.py?
- java - 如何从 ArrayList 中获取具有相同对象属性的对象列表
- postgresql - 为什么我做 LEFT JOIN 时没有应用优化?
- javascript - JS解释器如何工作?
- python - 将csv转换为数据框
- algorithm - 如何证明归并排序和插入排序的时间复杂度?
- docker - Has anyone modified the port number of orderer.example.com in the docker-compose-base.yaml file in fabric1.4 and then started the network?