2016-02-16 5 views
19

私は、メッセージが到着するたびにビープ音を鳴らすインスタントメッセージングアプリを持っているとしましょう。私はdebounceにビープ音を鳴らしたいけど、最初のメッセージが来たらビープ音を鳴らしたいし、次のものは聞こえません。RxSwift - Debounce/Throttle "inverse"

もう1つの例があります:私のアプリは入力通知を送信します(チャットしているユーザーがメッセージを入力していることがわかります)。私は入力を開始するときに入力通知を送信したいが、X秒間に新しい入力を送信するだけなので、入力したすべての文字について入力通知を送信しない。

これは意味がありますか?それのための演算子はありますか?それは既存の演算子で達成できますか?

これは私の最初の例のコードです。私は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用に更新し、RxSwift 3.0.0-beta.1で導入throtlleオペレータの新しい動作とthrottleオペレータ

を改善し、あなたはちょうどそのようにそれを使用することができます:

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

答えの

旧バージョン

window演算子を使用して、をフラットObservableに変換すると、flatMapが使用されます。

このサンプルコードは、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))