Angular 中的 SwitchMap 未按预期工作
SwitchMap not working as intended in Angular
我有一个搜索服务returning结果,如果用户提交两次,只有最后一次搜索应该return结果。
我在服务中有以下代码,视图(已在其他地方更新)具有请求所需的所有 post 正文信息。
此方法是使用 this.searchService.getResults()
从代码中的其他地方调用的
getResults() {
const view: SearchView = this.getCurrentSearch();
if (!view.query || view.query === '') {
return;
}
this.checkPermissions(view).subscribe(searchView => {
//do some stuff
this.cacheService
.cachedPost(this.url, searchView, () => {
return this.http.post(this.url, searchView);
})
.switchMap(res => this.pageTransform(res))
.subscribe(
// results here
);
});
}
`
从 运行 测试中我可以看到,如果我快速连续进行 3 次搜索,它们都会解决,而我只想要最后一次。
那是因为您多次调用 getResults()
方法,这会创建多个 Rx 链,并且所有这些链都会被处理。如果您希望 switchMap
正常工作,您需要仅保留对一条链的引用并将值推送给它:
private search$ = new Subject();
private searchSubscription = search$
.switchMap(view => this.checkPermissions(view)
.concatMap(searchView => this.cacheService.cachedPost(this.url, searchView, () => {
return this.http.post(this.url, searchView);
})
.concatMap(res => this.pageTransform(res))
)
.subscribe(...);
getResults() {
const view: SearchView = this.getCurrentSearch();
...
this.search$.next(view);
}
出于显而易见的原因,我没有测试这段代码,但我想你会明白这一点的。也不要忘记使用 this.searchSubscription.unsubscribe()
.
在 ngOnDestroy()
中退订
我有一个搜索服务returning结果,如果用户提交两次,只有最后一次搜索应该return结果。
我在服务中有以下代码,视图(已在其他地方更新)具有请求所需的所有 post 正文信息。
此方法是使用 this.searchService.getResults()
从代码中的其他地方调用的getResults() {
const view: SearchView = this.getCurrentSearch();
if (!view.query || view.query === '') {
return;
}
this.checkPermissions(view).subscribe(searchView => {
//do some stuff
this.cacheService
.cachedPost(this.url, searchView, () => {
return this.http.post(this.url, searchView);
})
.switchMap(res => this.pageTransform(res))
.subscribe(
// results here
);
});
}
`
从 运行 测试中我可以看到,如果我快速连续进行 3 次搜索,它们都会解决,而我只想要最后一次。
那是因为您多次调用 getResults()
方法,这会创建多个 Rx 链,并且所有这些链都会被处理。如果您希望 switchMap
正常工作,您需要仅保留对一条链的引用并将值推送给它:
private search$ = new Subject();
private searchSubscription = search$
.switchMap(view => this.checkPermissions(view)
.concatMap(searchView => this.cacheService.cachedPost(this.url, searchView, () => {
return this.http.post(this.url, searchView);
})
.concatMap(res => this.pageTransform(res))
)
.subscribe(...);
getResults() {
const view: SearchView = this.getCurrentSearch();
...
this.search$.next(view);
}
出于显而易见的原因,我没有测试这段代码,但我想你会明白这一点的。也不要忘记使用 this.searchSubscription.unsubscribe()
.
ngOnDestroy()
中退订