簡體   English   中英

Angular Observable 異步管道?

[英]Angular Observable async pipe?

考慮我有一個Rest API列出事件。

  • POST [203]:給出一系列事件。
  • POST [404]:未找到數據。

在這里,我的代碼。

export function httpFetchRetry<T>(source: Observable<T>): Observable<T> {
  let errorScanner = (errorCount: number, error: any) => {
    if (errorCount >= 5) throw error;
    else if (error.status === 404) throw error;
    else return errorCount + 1;
  };
    
  return source.pipe(retryWhen(e => {
    return e.pipe(scan(errorScanner, 0), delay(3000))
  }));
}
    
export function httpFetchMap<T>(source: Observable<T>): Observable<T[]>{
  return source.pipe(map(({data}: any):any[] => data));
}

private listEvents(user_id: string){

  let url: string = `${environment.apiEndpoint}/event`;
  let payload: any = { user_id };

  this.allEvents$ = this.http.post(url, payload)
    .pipe(httpFetchRetry)
    .pipe(httpFetchMap)
}

該代碼與async pipe一起工作得很好。

但是,現在我必須在UI上顯示這些狀態之一

<p> Loading </p>
<p> Loaded </p>
<p> No Data <p>
<p> Error <p>

Q1:如果我使用n 個異步管道,則會啟動n 個API 調用。 我如何避免這種情況?

Q2:我如何獲得這些狀態之一


目前,我正在解決這個問題

.toPromise()
  .then(data => {
    this.data= data;
    this.noDataFound = false;
  })
  .catch(err => {
    if(err.status === 404){
      this.noDataFound = true;
    }
    else {
      this.snackBar.open("Something went wrong. Please try again.", null , { duration: 2000 });
    }
  })
  .finally(() => { this.pageLoader = false });

Observables 與 Promises 的不同之處在於它們在subscribed之前什么都不做。 您可以將轉換管道鏈接到 Observable,但原始Observer函數將不會運行,直到包裝它們的Observable被訂閱。 它們與 Promise 的不同之處還在於 Observer 函數將為 Observable 的每個訂閱運行。

http方法在它們完成之前返回一個冷的、有限的 Observable 和一個發射。 這里的 Observer 函數是 http 調用本身。 檢查您的開發工具,您會發現在訂閱 Observable 之前沒有進行 http 調用。

async管道實際上在幕后subscribe Observable 並將其發射作為值展開,因此使用管道將導致 Observable 運行。 同樣, toPromise操作符也訂閱源Observable並將其轉換為 Promise,因此它通過立即運行而表現得像 Promise。

async管道通常是解包Observable的推薦方式,但是對於像 http 請求這樣的有限Observable ,您可能希望解包該值並將其保存在模板之外的某處:

private listEvents(user_id: string){
    
  let url: string = `${environment.apiEndpoint}/event`;
  let payload: any = { user_id };
    
  this.http.post(url, payload)
    .pipe(httpFetchRetry, httpFetchMap)
    .subscribe(s => this.allEvents = s);
}

一個好的設計模式是將這個值保存在一個服務中以供多個組件訪問。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM