Angular HTTP 請求複用方案

引言

Web應用,由於組件化大行其道,誕生了一個問題。typescript

image.png

如上圖所示,頂部導航欄組件須要請求當前登陸用戶的姓名,左側菜單欄組件須要請求當前登陸用戶的菜單權限,根據後臺的接口設計,二者都須要在應用初始化時獲取當前登陸用戶。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

image.png

同一個接口,發起了三次HTTP請求:設計

image.png

初代版本

流程以下:code

image.png

自定義一個觀察者對象,全部要獲取當前登陸用戶的組件要去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$;
  }
}

三個調用方都拿到了數據:

image.png

同一個接口,只發起了一次HTTP請求,節省了網絡資源:

image.png

  • 一樣實現HTTP複用功能。
  • 使用方法簡單,都是模板代碼,即使初學者也可按照範例進行編寫。

share

RxJS至關複雜,這裏的share也只是它的冰山一角。

share運算符不太好理解,RxJS相關的概念太多,這裏就不一一展開了,請參考文章:譯 RxJS: 理解 publish 和 share 操做符

固然,若是你沒有足夠地時間去學習探究share運算符,就大膽地使用上述示例代碼吧,這,就是最佳實踐。

總結

RxJS基於觀察者,但不止於觀察者,RxJS存在着衆多的操做符,且都不是那麼好理解,太偉大了。

相關文章
相關標籤/搜索