需要结合两个不纯的可观察量
Need to combine two impure observables
我需要向将 return 过滤和未过滤数据的同一端点发出 2 个 AJAX 请求。然后我需要合并结果并在处理中使用它们。
loadUnfilteredData() {
// remember status
const {status} = this.service.filters;
delete this.service.filters.status;
this.service.saleCounts$()
.subscribe((appCounts) =>
this.processUnfilteredData(appCounts)
);
// restore status
if (status) {
this.service.filters.status = status;
}
}
loadFilteredData() {
this.service.saleCounts$()
.subscribe((appCounts) =>
this.processFilteredData(appCounts)
);
}
问题是 this.service.saleCounts$()
是不纯的,而不是使用参数只是使用 this.service.filters
。
这就是为什么我必须存储 status
,然后将其从过滤器中删除,然后执行请求,然后恢复(因为其他请求使用相同的过滤器)。
所以我不能只combineLatest
处理两个可观察对象(因为我需要恢复)。
有什么解决办法吗?
(p.s。我知道这种方法很恶心,我知道状态管理和纯函数。只是想知道有没有漂亮的解决方案。
我相信你的约束要求这两个操作是 运行 顺序的,一个接一个,而不是像我们使用 combineLatest
.[=22 时通常的情况那样并行=]
为了 运行 两个 Observable 顺序,我们可以使用 switchMap
(作为现代 rxjs 中 pipe
调用中的运算符):
doFirstOperation()
.pipe(
switchMap(result => return doSecondOperation())
);
一个潜在的问题是,当您 switchMap
访问 doSecondOperation
的结果时,您将无法访问 doFirstOperation
的结果。要解决这个问题,我们可以这样做:
doFirstOperation()
.pipe(
switchMap(firstResult => return doSecondOperation())
.pipe(
map(secondResult => [firstResult, secondResult])
)
);
即,使用 map
将 switchMap
的返回值更改为包含两个值的数组。
将此与您对状态管理的“令人厌恶”的要求放在一起,您可以使用类似的东西:
loadData() {
const { status } = this.service.filters;
delete this.service.filters.status;
return this.service
.saleCounts$()
.pipe(
finalize(() => {
if (status) {
this.service.filters.status = status;
}
}),
switchMap(filteredData => {
return this.service
.saleCounts$() // unfiltered query
.pipe(map(unfilteredData => [filteredData, unfilteredData]));
})
)
.subscribe(results => {
const [filteredData, unfilteredData] = results;
this.processFilteredData(filteredData);
this.processUnfilteredData(unfilteredData);
});
}
我认为没有多少人认为它很漂亮,但它至少能让你以一种看起来像你使用的方式获得结果 combineLatest
,但可以解决你施加的限制不纯的方法。
我需要向将 return 过滤和未过滤数据的同一端点发出 2 个 AJAX 请求。然后我需要合并结果并在处理中使用它们。
loadUnfilteredData() {
// remember status
const {status} = this.service.filters;
delete this.service.filters.status;
this.service.saleCounts$()
.subscribe((appCounts) =>
this.processUnfilteredData(appCounts)
);
// restore status
if (status) {
this.service.filters.status = status;
}
}
loadFilteredData() {
this.service.saleCounts$()
.subscribe((appCounts) =>
this.processFilteredData(appCounts)
);
}
问题是 this.service.saleCounts$()
是不纯的,而不是使用参数只是使用 this.service.filters
。
这就是为什么我必须存储 status
,然后将其从过滤器中删除,然后执行请求,然后恢复(因为其他请求使用相同的过滤器)。
所以我不能只combineLatest
处理两个可观察对象(因为我需要恢复)。
有什么解决办法吗?
(p.s。我知道这种方法很恶心,我知道状态管理和纯函数。只是想知道有没有漂亮的解决方案。
我相信你的约束要求这两个操作是 运行 顺序的,一个接一个,而不是像我们使用 combineLatest
.[=22 时通常的情况那样并行=]
为了 运行 两个 Observable 顺序,我们可以使用 switchMap
(作为现代 rxjs 中 pipe
调用中的运算符):
doFirstOperation()
.pipe(
switchMap(result => return doSecondOperation())
);
一个潜在的问题是,当您 switchMap
访问 doSecondOperation
的结果时,您将无法访问 doFirstOperation
的结果。要解决这个问题,我们可以这样做:
doFirstOperation()
.pipe(
switchMap(firstResult => return doSecondOperation())
.pipe(
map(secondResult => [firstResult, secondResult])
)
);
即,使用 map
将 switchMap
的返回值更改为包含两个值的数组。
将此与您对状态管理的“令人厌恶”的要求放在一起,您可以使用类似的东西:
loadData() {
const { status } = this.service.filters;
delete this.service.filters.status;
return this.service
.saleCounts$()
.pipe(
finalize(() => {
if (status) {
this.service.filters.status = status;
}
}),
switchMap(filteredData => {
return this.service
.saleCounts$() // unfiltered query
.pipe(map(unfilteredData => [filteredData, unfilteredData]));
})
)
.subscribe(results => {
const [filteredData, unfilteredData] = results;
this.processFilteredData(filteredData);
this.processUnfilteredData(unfilteredData);
});
}
我认为没有多少人认为它很漂亮,但它至少能让你以一种看起来像你使用的方式获得结果 combineLatest
,但可以解决你施加的限制不纯的方法。