问题环境
> angular 4.0
问题描述
多次触发根据不同条件查询数据时,且接口响应慢的时候,有时会出现前一个请求覆盖后面一个请求的现象,造成展现数据和查询条件不统一的现象。
如图,每次修改筛选条件均会触发请求,频繁操作时就会出现返回结果相互覆盖的情况。
github 示例问题链接:github.com/NG-ZORRO/ng…
代码举例
service.ts
getList(param: any){
return this.httpClient.get(`/api/getList/${param}`);
}
component.ts
changeParam(param: any){
this.service.getList(param).subscribe(res => {
// res do something
// dataList 是和页面绑定的数据
this.dataList = res;
})
}
解决思路
a. 保证每次请求结果获取的都是最后一次请求的 b. 频繁操作时,取消掉之前的请求
b方案更合理,a方案虽然可以解决问题,可能会存多个状体而且会发多次请求。
下面是具体的解决方案 (很简单哦)
- angular4 以后引入了
HttpClient
,较之前的Promise,引入Observer,使用更顺手。
这里的请求其实是有返回的。
Subscription
返回的新对象可以用来订阅和取消订阅。
可以在component.ts
全局声明一个Subscription
的变量控制取消订阅。
getListSubscription: Subscription;
changeParam(param: any){
if(this.getListSubscription){
this.getListSubscription.unsubscribe();
}
this.getListSubscription = this.service.getList(param).subscribe(res => {
// res do something
// dataList 是和页面绑定的数据
this.dataList = res;
})
}
- 下面来说下另外一种方案解决,使用
rxjs
中的switchMap
解决:
// 声明一个数据流
getList$ = new Subject();
ngOnInit(){
this.getList$.pipe(
switchMap(() => {
return getList();
})
).subscribe(res => {
// res do something
// dataList 是和页面绑定的数据
this.dataList = res;
})
}
getList(){
return this.service.getList(param);
}
这两种方案都会再触发第二次请求前,将第一次发的请求置为cancel
掉。