结合rxjs,实现高效http请求
在项目中经常会碰到这样的需求,用户在输入框输入数据,需要实时调用后台api,根据结果对输入进行重复校验,或者搜索。
这里我们以github的用户搜索api做示例。
@Component({
template: `
<input (keyup)="search($event.target.value)">
<ul>
<li *ngFor="let user of userList">
{{user.login}}
<img [src]="user.avatar_url">
</li>
</ul>
`
})
export class HttpRequestComponent {
constructor(private httpClient: HttpClient) { }
userList: any[] = [];
//进行搜索 并且渲染到当前页面
search(name: string): void {
this.sendSearchRequest(name)
.subscribe(res => {
this.userList = res.items;
});
}
// 发送搜索请求
sendSearchRequest(name): Observable<{items: any[]}> {
return this.httpClient.get<{items: any[]}>('https://api.github.com/search/users?', {
params: {
q: name
}
});
}
}
以上代码足以完成需求,但是同时有以下几种隐患。
- 请求效率比较低,如果我输出
netease
那么因为输入的变化,n
,ne
,net
...netease
会合计发起共7次请求。其实只要最后一次netease
的结果。 - 多次请求的结果响应时间并不可控,从而渲染结果不可控。假设第一条
n
的搜索请求响应耗时10s,而其他请求包含netease
搜索都只需要1s,那页面最终的渲染结果为n的搜索结果,显然这样是不正确的。
解决上述问题需要用到几个操作符:
export class HttpRequestComponent implements OnInit {
constructor(private httpClient: HttpClient) { }
userList: any[] = [];
// 搜索subject
private onSearch$: Subject<string> = new Subject();
search(name: string): void {
// 每次输入都生产一个值
this.onSearch$.next(name);
}
private sendSearchRequest(name): Observable<{items: any[]}> {
return this.httpClient.get<{items: any[]}>('https://api.github.com/search/users?', {
params: {
q: name
}
});
}
ngOnInit(): void {
// 初始化的时候订阅search$,更新页面搜索结果。
this.onSearch$.asObservable()
.pipe(
// 注意先后顺序
// 防抖
debounceTime(1000),
// 变化才会请求
distinctUntilChanged(),
// 映射为新的Observable
switchMap(name => this.sendSearchRequest(name))
)
.subscribe(res => {
this.userList = res.items;
});
}
}
-
Subject 有着双重特性,它同时拥有 Observer 和 Observable 的行为。(多用于组件间通信场景)
// 发送值 subject.next( 2 ) // 订阅值 const subscription = subject.subscribe( (value) => console.log(value) )
-
debounceTime
前端常见的防抖策略,在一定时间内,只保留最后一次的值。 当用户在1000ms内连续输入的时候,我们只针对最后一次输入做请求,大大提升了请求效率。
-
distinctUntilChanged
只有值发生变化才会更新。只有内容变化才会触发请求。 部分浏览器输入中文可能会产生输入值不变,但是重复触发输入事件的问题
-
switchMap
有点类似于Promise
。实际作用为完成前一个observable,映射成一个新的observable。 实际在angular中,当在上述的重复请求业务场景中,例如搜索,翻页等等,当前一条请求未完成,而后一条请求已经发出,那么此操作符会导致前一条请求被取消,从而保证了请求以及结果的顺序。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!