2017-02-03 9 views
10

का उपयोग कर आरएक्सजेएस ऑपरेटरों को नए ऑपरेटर में मिलाएं I अक्सर मुझे स्वयं को पर्यवेक्षकों के समान अनुक्रम को अवलोकन करने के लिए जोड़ते हैं, उदा।टाइपस्क्रिप्ट

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

मैं एक छोटे से पुन: प्रयोज्य ऑपरेटर में इन 3 ऑपरेटरों संयोजित करने का उपाय (जैसे .cache('some text')) के लिए देख रहा हूँ कि मैं किसी भी नमूदार के लिए श्रृंखला कर सकते हैं। मैं इसे टाइपस्क्रिप्ट में कैसे परिभाषित कर सकता हूं, ताकि मैं 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

@ एनपीएन हाँ, त्रुटियों और समापन रचनाकृत अवलोकन योग्य ग्राहकों द्वारा प्राप्त किए जाएंगे। ऐसा कुछ भी नहीं है जिसे यहां करने की आवश्यकता है। – cartant

+0

जब मैं इस दृष्टिकोण को आज़माता हूं, तो मुझे यह त्रुटि मिलती है: 'अपवाद: अनकॉल्ड (वादे में): त्रुटि: त्रुटि ./DashboardComponent क्लास डैशबोर्ड कॉम्पोनेंट - इनलाइन टेम्पलेट: 2: 4 के कारण: __WEBPACK_IMPORTED_MODULE_2_rxjs_Observable __। Observable.of (...) .restrictToCommand एक फ़ंक्शन नहीं है टाइपरर: __WEBPACK_IMPORTED_MODULE_2_rxjs_Observable __। Observable.of (...)। प्रतिबंधितToCommand एक functio नहीं है। कोई विचार? –

2

cartant के जवाब से ऊपर अच्छी तरह से काम करता है, और उत्तर देता है प्रश्न पूछा गया था (मैं इसे टाइपस्क्रिप्ट में कैसे परिभाषित कर सकता हूं, ताकि मैं आरएक्सजे/पर्यवेक्षक और इस ऑपरेटर को आयात कर सकूं, जैसे मैं आरएक्सजेएस ऑपरेटरों के साथ करता हूं?)

मैं हाल ही में let ऑपरेटर जो करता है, तो आप वास्तव में समारोह एक ऑपरेटर के रूप में लागू करने के लिए, अभी भी आप अपने कोड सूख दूँगी की जरूरत नहीं है की खोज की।

मैं अपने रेल बैकएंड के साथ इंटरफ़ेस के लिए एक कोणीय 2 सेवा को लागू करने के लिए शुरू कर रहा था और जानता था कि मेरी अधिकांश एपीआई कॉल बहुत समान दिखती हैं, इसलिए मैं एक समारोह में सामान्य सामानों को आजमाने और रखना चाहता था।

लगभग सभी कॉल निम्न करेगा: एक त्रुटि पर

  1. पुन: प्रयास करें (मेरी समारोह नीचे उस मोर्चे पर और अधिक काम करने की जरूरत)
  2. (एक टाइपप्रति स्थानीय रूप से परिभाषित वर्ग में http प्रतिक्रिया के नक्शे json-typescript-mapper के माध्यम से)
  3. संभाल त्रुटियों

यहां एक सामान्य समारोह के माध्यम से अपने उपयोग मेरी http प्रतिक्रियाओं को let ऑपरेटर (हाथ का एक उदाहरण है leResponse) 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})); 
    }