2016-11-18 172 views
0

我對ReactiveX原則相對比較陌生,但我是迄今爲止所學的東西。我有一個挑戰,我已經提出了一些想法,但我想獲得更有經驗的意見:鏈式rxjs可觀察的運營商

我有幾個方法返回一個Observable。每個人創建一個類似莊園的Observable,然後鏈接相同的確切操作符。是否有任何方法將這些運算符抽象出來,這樣我就不必每種方法都重複這些代碼。

例如,這就是我現在所擁有的:

public get(endpoint: string, options?: RequestOptions): Observable<any> { 
     return this.http.get(endpoint, requestOptions) 
     .map((response: Response) => { 
      let responseBody = response.json(); 
      return responseBody; 
     }) 
     .catch((error: Response) => { 
      let responseError = new ErrorResponse(error.status.toString(), error.json()); 
      return Observable.throw(responseError); 
     }) 
     .publishReplay() 
     .refCount() 
     .share(); 
    } 

    public put(endpoint: string, body: any, options?: RequestOptions): Observable<any> { 
     return this.http.put(endpoint, body, requestOptions) 
     .map((response: Response) => { 
      let responseBody = response.json(); 
      return responseBody; 
     }) 
     .catch((error: any) => { 
      this.logger.logRequestError('PUT', endpoint, error); 
      return Observable.throw(error); 
     }) 
     .publishReplay() 
     .refCount() 
     .share(); 
    } 

我想借此地圖,抓,publishReplay,引用計數,分享運營商,把他們在自己的運營商,這樣我可以這樣做:

public get(endpoint: string, options?: RequestOptions): Observable<any> { 
     return this.http.get(endpoint, requestOptions).myOperator(); 
    } 

    public put(endpoint: string, body: any, options?: RequestOptions): Observable<any> { 
     return this.http.put(endpoint, body, requestOptions).myOperator(); 
    } 

    // define myOperator as something like: 

     .map((response: Response) => { 
      let responseBody = response.json(); 
      return responseBody; 
     }) 
     .catch((error: Response) => { 
      let responseError = new ErrorResponse(error.status.toString(), error.json()); 
      return Observable.throw(responseError); 
     }) 
     .publishReplay() 
     .refCount() 
     .share(); 

    // end definition 

回答

0

會是這樣的工作嗎?使用bind()您可以推遲執行您的http調用。我不知道你正在使用哪個庫,如果http.get()返回一個Observable,那麼你可以調用它並將返回的observable傳遞給handleHttpCall,因爲Observables是(幾乎總是)懶惰,並且不會在訂閱之前運行代碼。

public get(endpoint:string, options?: RequestOptions): Observable<any> { 
    return handleHttpCall(this.http.get.bind(endpoint, requestOptions)); 
} 

private handleHttpCall(httpAction) { 
    return httpAction() 
     .map((response: Response) => { 
      let responseBody = response.json(); 
      return responseBody; 
     }) 
     .catch((error: Response) => { 
      let responseError = new ErrorResponse(error.status.toString(), error.json()); 
      return Observable.throw(responseError); 
     }) 
     .publishReplay() 
     .refCount() 
     .share(); 
} 
+0

馬克,謝謝。這實際上正是我現在正在做的。我不知道是否有更多的「被動」處理方式,我可以簡單地在http.get()調用的末尾添加一個運算符。 (是的,我的http.get()確實返回一個可觀察值。) –

+0

因爲你的http.get()返回一個可觀察值,所以你可以跳過bind()塊。將承諾轉換爲可觀察對象的更具反應性的方法是使用'Rx.Observable.defer(()=> this.http.get(endpoint,requestOptions))' –