2017-02-03 22 views
10

私は自分自身が観測者に同じ演算子のシーケンスを追加することがよくあります。TypeScriptを使用してRxJS演算子を新しい演算子に結合する

observable$ 
    .do(x => console.log('some text', x)) 
    .publishReplay() 
    .refCount(); 

私が観察可能にチェーンをできることを小さな再利用可能なオペレータ(例えば.cache('some text'))でこれら3つの演算子を結合する方法を探しています。これをTypescriptでどのように定義すれば、rxjs/Observableとこの演算子をrxjs演算子と同じようにインポートできますか?

答えて

16

、あなたが説明した演算子を実装し、以下の内容でcache.tsファイルを作成するには、次の

import { Observable } from "rxjs/Observable"; 
import "rxjs/add/operator/do"; 
import "rxjs/add/operator/publishReplay"; 

// Compose the operator: 

function cache<T>(this: Observable<T>, text: string): Observable<T> { 
    return this 
    .do(x => console.log(text, x)) 
    .publishReplay() 
    .refCount(); 
} 

// Add the operator to the Observable prototype: 

Observable.prototype.cache = cache; 

// Extend the TypeScript interface for Observable to include the operator: 

declare module "rxjs/Observable" { 
    interface Observable<T> { 
    cache: typeof cache; 
    } 
} 

をそして、このようにそれを消費:上記

import { Observable } from "rxjs/Observable"; 
import "rxjs/add/observable/of"; 
import "./cache"; 

let cached = Observable.of(1).cache("some text"); 
cached.subscribe(x => console.log(x)); 
+0

私は同様の質問がありました。これは良い解決策のようです。これは単なる演算子チェーンなので、エラーを処理してデフォルトで完了しますか?それはすべきだと思われますが、私はrxjsの新人です。 – nPn

+0

@nPnしかし、エラーと補完は、構成された観測可能な加入者によって受信されます。ここでは何もする必要はありません。 – cartant

+0

このアプローチを試してみると、次のようなエラーが表示されます。 '例外:未知(未定):エラー:./DashboardComponentクラスのエラーDashboardComponent - インラインテンプレート:2:4原因:__WEBPACK_IMPORTED_MODULE_2_rxjs_Observable __。Observable.of(...) .restrictToCommandは関数ではありません TypeError:__WEBPACK_IMPORTED_MODULE_2_rxjs_Observable __。Observable.of(...)。restrictToCommandは関数ではありません。何か案は? –

2

cartantの答えはうまく機能、および回答質問した質問(rxjs演算子と同じように、rxjs/Observableとこの演算子をインポートできるように、これをTypescriptでどのように定義できますか?)私は最近、あなたが実際にオペレータとして実現される機能を持っている必要がない場合はletオペレータを発見

、まだあなたがあなたのコードを乾燥させます。

私は、レールバックエンドとのインターフェイスをとるための2角型サービスの実装を開始していました。私のAPI呼び出しのほとんどが非常によく似ていることを知っていましたので、関数に多くの共通のものを入れたいと思っていました。

ほとんどすべての呼び出しは次の操作を行います:エラーの

  1. 、リトライ(以下私の関数は、その前面に多くの作業を必要とする)
  2. json-typescript-mapper経由(typescriptです中に局所的に定義されたクラスをHTTPレスポンスをマッピングここでは)
  3. ハンドルエラー

共通機能により、私のHTTP応答にlet演算子(手私の使用例でありますleResponse)をrxjs letオペレータを使用して実行します。

handleResponse<T>({klass, retries=0} :{klass:any,retries?:number }) : (source: Observable<Response>) => Observable<T> { 
    return (source: Observable<Response>) : Observable<T> => { 
     return source.retry(retries) 
      .map((res) => this.processResponse(klass,res)) 
      .catch((res) => this.handleError(res)); 
    } 
    } 

    processResponse(klass, response: Response) { 
    return deserialize(klass, response.json()); 
    } 

    handleError(res: Response) { 
    const error = new RailsBackendError(res.status, res.statusText); 
    return Observable.throw(error); 
    } 

    getUserList({page=1,perPage=30,retry=0}: { page?:number, perPage?:number, retry?:number }={}) : Observable<UserList> { 
    const requestURL = `/api/v1/users/?${this.apiTokenQueryString}&page=${page}&per_page=${perPage}`; 
    return this.http.get(requestURL).let(this.handleResponse<UserList>({klass: UserList})); 
    } 
関連する問題