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
存在着衆多的操做符,且都不是那麼好理解,太偉大了。