2017-02-03 45 views
10

'u kullanarak yeni operatöre birleştirin. Kendimi sık sık gözlemlenebilir öğelere aynı işleç dizisini ekleyerek buluyorum.RxJS işleçlerini TypeScript

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

Ben küçük yeniden kullanılabilir operatörü bu 3 operatörleri birleştirmek için bir yol (örneğin .cache('some text')) arıyorum ben herhangi gözlenebilir için zincir bunu başaramaz. Bunu rxjs operatörleriyle yaptığım gibi rxjs/Gözlemlenebilir ve bu operatörü içe aktarabilmem için, bunu Typescript'te nasıl tanımlayabilirim?

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

Ve böyle tüketmek:

cevap

16

Tarif etmiş operatörü uygulamak için aşağıdaki içeriğe sahip bir cache.ts dosyası oluşturmak

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

Benzer bir sorum vardı, bu iyi bir çözüm gibi görünüyor. Bu sadece bir operatör zinciri olduğundan, hataları ele alıyor ve varsayılan olarak tamamlanıyor mu? Olması gerektiği gibi görünüyor, ama ben rxjs için yeniyim. – nPn

+0

@nPn Yep, hatalar ve tamamlamalar, gözlemlenen gözlemlenebilir aboneler tarafından alınacaktır. Burada yapılması gereken bir şey yok. – cartant

+0

Bu yaklaşımı denediğimde, şu hatayı alıyorum: EXCEPTION: Yakalanmadı (vaatte): Hata: ./DashboardComponent sınıfı DashboardComponent hatası - inline template: 2: 4 neden oldu: __WEBPACK_IMPORTED_MODULE_2_rxjs_Observable __. Observable.of (...) .restrictToCommand bir işlev değil TypeError: __WEBPACK_IMPORTED_MODULE_2_rxjs_Observable __. Observable.of (...). restrictToCommand bir işlev değildir. Herhangi bir fikir? –

2

cartant cevabı yukarıdaki iyi çalışıyor ve cevapları sorulan soru (Bunu rxjs operatörleri ile yaptığım gibi rxjs/Gözlemlenebilir ve bu operatörün ithalatını yapabilmem için, bunu Typescript'te nasıl tanımlayabilirim?)

Geçenlerde aslında hala kodunuzu KURU sağlayacak bir operatörü olarak uygulanan işlevi olması gerekmiyorsa let operatörü keşfetti.

Raylarımın arka ucuyla arabirim oluşturmak için bir açısal 2 hizmetini uygulamaya başlıyordum ve api çağrılarımın çoğunun çok benzer görüneceğini biliyordum, böylece bir işlevdeki ortak şeylerin çoğunu denemek istedim.

aramaların neredeyse tamamı aşağıdakileri: Bir hatayı

  1. yeniden deneme
  2. json-typescript-mapper yoluyla (daktilo yerel olarak tanımlı sınıf içine http yanıtı map (benim işlevi aşağıda bu cephede daha çalışmak gerekir))
  3. sap hataları
  4. İşte

ortak işlevi aracılığıyla kullanımım benim http yanıtlarına let operatörü (el örneğidir leResponse) rxjs üzerinden operatöre izin verir.

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