Web
应用,由于组件化大行其道,诞生了一个问题。typescript
如上图所示,顶部导航栏组件须要请求当前登陆用户的姓名,左侧菜单栏组件须要请求当前登陆用户的菜单权限,根据后台的接口设计,二者都须要在应用初始化时获取当前登陆用户。json
导航栏发起HTTP
请求,获取当前登陆用户信息。网络
菜单栏发起HTTP
请求,获取当前登陆用户信息。组件化
二者请求到的数据是相同的,彻底能够共用一个请求来完成这个任务,请求两次无疑耗费网络资源。post
可是就这么一个简单的任务,却迭代了好几个实现版本才完美解决。学习
以下所示,屡次请求同一接口数据,实际业务场景确定是跨组件的,这里只是举一个最简单的例子:this
export class AppComponent implements OnInit { constructor(private httpClient: HttpClient) { } ngOnInit(): void { this.getTeachers(); } getTeachers(): void { this.request().subscribe((teachers: Array<Teacher>) => { console.log('request - 1', teachers); }); this.request().subscribe((teachers: Array<Teacher>) => { console.log('request - 2', teachers); }); this.request().subscribe((teachers: Array<Teacher>) => { console.log('request - 3', teachers); }); } request(): Observable<Array<Teacher>> { return this.httpClient.get<Array<Teacher>>('/assets/mock/teacher.json'); } }
三个调用方都拿到了数据:spa
同一个接口,发起了三次HTTP
请求:设计
流程以下:code
自定义一个观察者对象,全部要获取当前登陆用户的组件要去currentLoginUser$
观察者上进行订阅。
系统初始化时,请求接口数据,将结果next
进观察者对象中。
最新在StackOverflow
上发现能够采用RxJS share
方式完美地解决该问题,以下所示:
定义一个观察者对象teachers$
,可是这个对象不须要咱们本身维护,咱们只须要调用httpClient
的方法,将它返回的可观察对象使用share
操做符过滤便可。
以后改造request
方法,返回teachers$
可观察对象。
export class AppComponent implements OnInit { teachers$: Observable<Array<Teacher>>; constructor(private httpClient: HttpClient) { this.teachers$ = this.httpClient.get<Array<Teacher>>('/assets/mock/teacher.json').pipe(share()); } ngOnInit(): void { this.getTeachers(); } getTeachers(): void { this.request().subscribe((teachers: Array<Teacher>) => { console.log('request - 1', teachers); }); this.request().subscribe((teachers: Array<Teacher>) => { console.log('request - 2', teachers); }); this.request().subscribe((teachers: Array<Teacher>) => { console.log('request - 3', teachers); }); } request(): Observable<Array<Teacher>> { return this.teachers$; } }
三个调用方都拿到了数据:
同一个接口,只发起了一次HTTP
请求,节省了网络资源:
HTTP
复用功能。RxJS
至关复杂,这里的share
也只是它的冰山一角。
share
运算符不太好理解,RxJS
相关的概念太多,这里就不一一展开了,请参考文章:译 RxJS: 理解 publish 和 share 操做符
固然,若是你没有足够地时间去学习探究share
运算符,就大胆地使用上述示例代码吧,这,就是最佳实践。
RxJS
基于观察者,但不止于观察者,RxJS
存在着众多的操做符,且都不是那么好理解,太伟大了。