2015-08-07 5 views
16

आरएक्सजेवा v1.0.13 ने नए प्रकार के एक पर्यवेक्षक पेश किए: आरएक्स। सिंगल। यह अनुरोध-प्रतिक्रिया मॉडल को बहुत अच्छा लगा, लेकिन मानक दुष्प्रभावों की कमी है जैसे ऑपरेटरों को doOnNext()। इसलिए, परिणामस्वरूप कई चीजें घटित करना बहुत मुश्किल है।आरएक्स के कैशिंग/गर्म संस्करण को कैसे बनाया जाए।

मेरा विचार एक ही एकल उदाहरण के लिए एकाधिक सदस्यता के साथ doOnNext() को प्रतिस्थापित करना था। लेकिन इससे अंडरलेइंग काम कई बार किया जा सकता है: प्रत्येक सदस्यता के बाद एक बार।

उदाहरण rx.Single कार्यान्वयन:

private class WorkerSubscribe<SomeData>() : Single.OnSubscribe<SomeData> { 
    override fun call(sub: SingleSubscriber<in SomeData>) { 
     try { 
      val result = fetchSomeData() 
      sub.onSuccess(result) 
     } catch(t: Throwable) { 
      sub.onError(t) 
     } 
    } 
} 

val single = Single.create<SomeData>(WorkerSubscribe()) 

उपयोग:

single.subscribe({}, {}) 
single.subscribe({}, {}) // Data is fetched for the second time 

यह एकल के एक उदाहरण बनाने के लिए संभव है कि नहीं fetchSomeData() कई बार यहां तक ​​कि जब single.subscribe होगा() कई बार कहा जाता है, लेकिन कैश और एक ही परिणाम वापस? BehaviorSubject या AsyncSubject

उत्तर

3

आप RxJava Subject की जरूरत है। यह उत्सर्जन को Observable से कैश करना है और उन्हें बाद में Subscriber एस में पुन: उत्पन्न करना है।

+2

नहीं यह एक कदम पीछे पहली जगह में एकल का उपयोग करने से होगा? – atok

+3

क्या आप एक कोड उदाहरण पोस्ट करेंगे ताकि समाधान को अनुमानित करने की आवश्यकता न हो? –

0

cache() operator की जांच करें:

+0

यह उत्तर की तुलना में एक टिप्पणी की तरह लगता है क्योंकि "कैश ऑपरेटर के बारे में और जानें" के अलावा यहां कोई निश्चित सुझाव नहीं है –

+0

'rx.Single' में 'कैश()' विधि नहीं है। –

0

आप एक व्यवहार विषय/ReplaySubject/AsyncSubject बना सकते हैं - और फिर उस पर सिंगल को कॉल करें।

+1

क्या आप एक कोड उदाहरण पोस्ट करेंगे ताकि समाधान को अनुमानित करने की आवश्यकता न हो? –

+0

उन वर्गों में से कोई भी 'toSingle()' विधि नहीं है। हालांकि, आप 'सिंगल। फ्रॉम ऑब्सर्जेबल() 'बना सकते हैं; जो एक 'विषय' से विरासत में मिलता है। – Bryan

0

मैं वैकल्पिक हल कर दिया, कि मैं इसके साथ खुश नहीं हूँ, लेकिन यह काम करता है:

public class Network { 
    private Object data; 
    private Single<Object> dataSingle; 

    public Single<Object> getData { 
     if (data == null) { 
     if (dataSingle == null) { 
      dataSingle = Single.create(...) 
      .doOnSuccess(data -> this.data = data;) 
      .sibscribeOn(..); 
     } 
     return dataSingle; 
     } else { 
     return Single.just(data); 
     } 
    } 
} 
1

मैं सिर्फ समान व्यवहार की जरूरत है और कुछ समाधान मिल गया।

आप Single से Observablecache() लागू कर सकते हैं और फिर इसे Single पर परिवर्तित कर सकते हैं।

yourSingle.toObservable().cacheWithInitialCapacity(1).toSingle() 

मैं cacheWithInitialCapacity(1) सिर्फ cache() एक अनुकूलन के रूप में के बजाय का उपयोग करें - Single एक से अधिक आइटम फेंकना कभी नहीं होगा।

 

यह भी अच्छा विचार है Transformer कार्यान्वयन

public class SingleUtils { 

    public static <T> Single.Transformer<T, T> cached() { 
     return single -> single.toObservable() 
      .cacheWithInitialCapacity(1) 
      .toSingle(); 
    } 
} 

ताकि आप केवल बुला

yourSingle.compose(SingleUtils.cached()) 

संपादित करें द्वारा जहां भी आप चाहते कैशिंग उपयोग कर सकते हैं प्रदान करने के लिए: से शुरू आरएक्सजेवा 1.2.2 इसे जोड़ा गया है (https://github.com/ReactiveX/RxJava/releases/tag/v1.2.2)

लागू वास्तव में इस तरह से (https://github.com/ReactiveX/RxJava/pull/4757)

संबंधित मुद्दे