角度可观察的异步管道?

时间:2019-02-08 22:12:00

标签: angular rxjs httpclient

考虑到我有一个 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)
}

该代码与 异步管道 正常工作。

但是,现在我必须在 UI 上显示这些状态之一。

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

  

问题1::如果我使用 n 个异步管道,则会启动 n 个API调用。如何避免这种情况?

     

第二季度:我如何成为这些状态之一?


目前,我正在解决此问题

.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 });

1 个答案:

答案 0 :(得分:0)

可观测对象与Promise的不同之处在于,它们直到subscribed为止都不做。您可以将转换管道链接到Observable,但是原始的Observer函数只有在包装了Observable的转换后才能运行。它们与Promises的不同之处还在于,对Observable的每个订阅都将运行Observer函数。

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);

}

一种好的设计模式是将该值保存在服务中,以供多个组件访问。

相关问题