2016-02-16 9 views
19

मान लें कि मेरे पास एक त्वरित संदेश एप्लिकेशन है जो हर बार एक संदेश आने पर बीप ध्वनि बजाता है। मैं debounce बीप करना चाहता हूं, लेकिन मैं पहले संदेश के लिए बीप ध्वनि खेलना चाहता हूं, न कि निम्न के लिए (एक समय में, कहें, 2 सेकंड में)।RxSwift - Debounce/Throttle "उलटा"

एक और उदाहरण हो सकता है: मेरा ऐप टाइपिंग नोटिफिकेशन भेजता है (इसलिए जिस उपयोगकर्ता के साथ मैं चैट कर रहा हूं वह देख सकता है कि मैं एक संदेश टाइप कर रहा हूं)। जब मैं टाइपिंग शुरू करता हूं, तो मैं एक टाइपिंग अधिसूचना भेजना चाहता हूं, लेकिन केवल एक्स-सेकेंड अंतराल में नए भेजता हूं, इसलिए मैं टाइप किए गए प्रत्येक चरित्र के लिए टाइपिंग अधिसूचना नहीं भेजता हूं।

क्या यह समझ में आता है? क्या इसके लिए कोई ऑपरेटर है? क्या मौजूदा ऑपरेटरों के साथ इसे हासिल किया जा सकता है?

यह पहला उदाहरण है। मैं अब debounce के साथ इसे हल कर रहा हूं, लेकिन यह आदर्श नहीं है। अगर मुझे 1 सेकंड के अंतराल में 1000 संदेश प्राप्त होते हैं, तो यह अंतिम संदेश आने तक ध्वनि नहीं चलाएगा (मैं पहली बार ध्वनि बजाना चाहता हूं)।

self.messagesHandler.messages 
      .asObservable() 
      .skip(1) 
      .debounce(2, scheduler: MainScheduler.instance) 
      .subscribeNext { [weak self] message in 
        self?.playMessageArrivedSound() 
      }.addDisposableTo(self.disposeBag) 

धन्यवाद!

+0

है यह एक अच्छा स्पष्टीकरण https://medium.com/@dkhuong291/throttle-vs-debounce-in-rxswift-86f8b303d5d4 – onmyway133

उत्तर

20

RxSwift 3 के लिए नवीनीकृत और बेहतर throttle ऑपरेटर

throtlle ऑपरेटर के नए व्यवहार, RxSwift 3.0.0-beta.1 में शुरू की के साथ, आप यह बस ऐसे ही उपयोग कर सकते हैं:

downloadButton.rx.tap 
    .throttle(3, latest: false, scheduler: MainScheduler.instance) 
    .subscribe(onNext: { _ in 
     NSLog("tap") 
    }).addDisposableTo(bag) 

जवाब का पुराना संस्करण

window ऑपरेटर का उपयोग करें और फिर का उपयोग कर Observable<Observable<Type>> पर फ्लैट Observable पर बदलें।

यह नमूना कोड प्रत्येक 3 सेकंड विंडोज़ में पहली टैप के लिए 'टैप' प्रिंट करता है (या यदि टैप गिनती 10000 से अधिक हो)।

downloadButton.rx_tap 
    .window(timeSpan: 3, count: 10000, scheduler: MainScheduler.instance) 
    .flatMap({ observable -> Observable<Void> in 
     return observable.take(1) 
    }) 
    .subscribeNext { _ in 
     NSLog("tap") 
    }.addDisposableTo(bag) 
+0

मैं है वर्तमान में एक समान समाधान का उपयोग कर, लेकिन मुझे लगता है कि सुधार के लिए जगह है। मैं डबल सदस्यता से बचना चाहता हूं। जवाब के लिए धन्यवाद! –

+3

निश्चित रूप से सुधार के लिए जगह थी। अब यह दोहरी सदस्यता के बिना काम करता है। –

1

विंडो एक अच्छा समाधान है, लेकिन मुझे नमूना ऑपरेटर अधिक अंतर्ज्ञानी और सही व्यवहार के साथ भी मिलता है।

messagesHandler.messages 
       .sample(Observable<Int>.timer(0.0, period: 2.0, scheduler: MainScheduler.instance)) 
       .subscribeNext { [weak self] message in 
        self?.playMessageArrivedSound() 
       }.addDisposableTo(self.disposeBag) 

थ्रॉटल ऑपरेशन ऐसा नहीं करता जो मैंने सोचा था।

लोगों को भी थ्रोटल को खोजने के लिए बहुत भ्रामक है:

"। थ्रोटल केवल आगे एक घटना एक बार स्रोत नमूदार समय की निर्दिष्ट अवधि के लिए ईवेंट भेजने से बंद कर दिया है यह नियमित घटना वितरण के साथ अच्छी तरह से काम नहीं करता है" for more details

इस मामले में, फिल्टर आप चाहते हैं

sample(Observable<Int>.timer(0.0, period: 2.0, scheduler: MainScheduler.instance)) 
संबंधित मुद्दे