2017-02-03 35 views
10

Tôi thường tìm thấy tự thêm cùng một chuỗi các toán tử vào các quan sát, ví dụ:Kết hợp các toán tử RxJS vào toán tử mới bằng cách sử dụng TypeScript

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

Tôi đang tìm kiếm một cách để kết hợp những 3 nhà khai thác trong một nhà điều hành tái sử dụng nhỏ (ví dụ .cache('some text')) mà tôi có thể chuỗi bất kỳ quan sát được. Làm thế nào tôi có thể xác định điều này trong Typescript, để tôi có thể nhập rxjs/Observable và toán tử này, giống như tôi làm với các toán tử rxjs?

Trả lời

16

Để thực hiện điều hành bạn đã mô tả, tạo một tệp cache.ts với nội dung sau:

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

Và tiêu thụ nó như thế này:

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

Tôi có một câu hỏi tương tự, điều này trông giống như một giải pháp tốt. Vì đây chỉ là một chuỗi các toán tử, nó có xử lý các lỗi và hoàn thành theo mặc định không? Có vẻ như nó nên, nhưng tôi mới đến rxjs. – nPn

+0

@nPn Yep, lỗi và số lần hoàn thành sẽ được nhận bởi người đăng ký có thể quan sát được. Không có gì cần phải làm ở đây. – cartant

+0

Khi tôi thử phương pháp này, tôi nhận được lỗi này: 'Ngoại lệ: Không bắt buộc (trong lời hứa): Lỗi: Lỗi trong ./DashboardComponent class DashboardComponent - mẫu nội tuyến: 2: 4 do: __WEBPACK_IMPORTED_MODULE_2_rxjs_Observable __. Observable.of (...) .restrictToCommand không phải là hàm LoạiError: __WEBPACK_IMPORTED_MODULE_2_rxjs_Observable __. Observable.of (...). limitsToCommand không phải là dấu chấm câu. Bất kỳ ý tưởng? –

2

câu trả lời cartant của trên hoạt động tốt, và trả lời cho câu hỏi đã được hỏi (Làm thế nào tôi có thể xác định điều này trong Typecript, để tôi có thể nhập rxjs/Observable và toán tử này, như tôi làm với các toán tử rxjs?)

Gần đây tôi phát hiện ra điều hành let mà nếu bạn không thực sự cần phải có chức năng thực hiện như một hành, vẫn sẽ cho phép bạn KHÔ lên mã của bạn.

Tôi bắt đầu triển khai dịch vụ góc 2 để giao tiếp với phụ trợ đường ray và biết rằng hầu hết các cuộc gọi api của tôi sẽ trông rất giống nhau vì vậy tôi muốn thử và đặt nhiều thứ phổ biến vào một chức năng.

Hầu như tất cả các cuộc gọi sẽ làm như sau:

  1. retry trên một lỗi (chức năng của tôi dưới đây cần làm việc nhiều hơn về phía trước đó)
  2. bản đồ phản ứng http thành một nguyên cảo cục bộ được định nghĩa lớp (thông qua json-typescript-mapper)
  3. xử lý lỗi

Dưới đây là một ví dụ về sử dụng của tôi let điều hành để đáp ứng http tôi thông qua một chức năng chung (tay leResponse) thông qua toán tử rxjs.

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})); 
    } 
Các vấn đề liên quan