2016-02-16 16 views
19

Załóżmy, że mam aplikację do obsługi wiadomości błyskawicznych, która odtwarza dźwięk za każdym razem, gdy nadejdzie wiadomość. Chcę wydobywać sygnały dźwiękowe, ale chciałbym odtworzyć sygnał dźwiękowy dla pierwszej wiadomości, a nie dla następnych (w czasie, powiedzmy, 2 sekundy).RxSwift - Odbijanie/blokowanie "odwrotne"

Innym przykładem może być: moja aplikacja wysyła powiadomienia na klawiaturze (dzięki czemu użytkownik, z którym rozmawiam, widzi, że piszę wiadomość). Chcę wysłać powiadomienie na klawiaturze, gdy zacznę pisać, ale wysyłam nowe tylko w odstępach X-sekundowych, więc nie wysyłam powiadomień na klawiaturze dla każdego wpisanego przeze mnie znaku.

Czy to ma sens? Czy istnieje operator? Czy można to osiągnąć przy pomocy istniejących operatorów?

To jest mój kod dla pierwszego przykładu. Rozwiązuję go teraz pod numerem debounce, ale nie jest idealny. Jeśli otrzymam 1000 wiadomości w odstępach co 1 sekundę, nie będzie odtwarzał dźwięku, dopóki nie nadejdzie ostatnia wiadomość (chciałbym odtworzyć dźwięk na pierwszym).

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

Dzięki!

+0

Jest to dobre wytłumaczenie https://medium.com/@dkhuong291/throttle-vs-debounce-in-rxswift-86f8b303d5d4 – onmyway133

Odpowiedz

20

Aktualizacja dla RxSwift 3 i poprawiła throttle operatora

Dzięki nowej zachowania throtlle operatora, wprowadzonej w RxSwift 3.0.0-beta.1, można używać go tak po prostu:

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

Stara wersja odpowiedzi

Użyj operatora window, a następnie przekształć Observable<Observable<Type>> na płaski Observable, używając flatMap.

Ten przykładowy kod wyświetla "dotknij" tylko dla pierwszego stuknięcia w każdym oknie 3-sekundowym (lub gdy liczba stuknięć przekracza 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

jestem obecnie korzystam z podobnego rozwiązania, ale uważam, że jest miejsce na poprawę. Chciałbym uniknąć podwójnej subskrypcji. Dzięki za odpowiedź! –

+3

Zdecydowanie można było poprawić. Teraz działa bez podwójnej subskrypcji. –

1

Okno to świetne rozwiązanie, ale uważam, że operator przykładowy jest bardziej intuicyjny i ma poprawne zachowanie.

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

Przepustnica nie działa tak, jak myślałem.

Dla osób, które również znajdują się przepustnica jest zbyt skomplikowane:

„przepustnica będzie tylko do przodu zdarzenie raz źródłem obserwowalne zatrzymał wysyłanie zdarzenia dla określonego okresu czasu to nie działa dobrze z regularnego dostarczania zdarzeń” for more details.

W tym przypadku filtr chcesz to

sample(Observable<Int>.timer(0.0, period: 2.0, scheduler: MainScheduler.instance)) 
Powiązane problemy