2017-02-21 47 views
1

, имеющие две наблюдаемыхRxJava только испускает элемент, если другой источник не будет пункт в течение некоторого периода

Observable<Void> cancelButtonClick 
      = RxView.clicks(btnCancel); 
Observable<Void> actionButtonClick 
      = RxView.clicks(btnSomeAction) 

Проблема

Попытки испускают значения из actionButtonClick потока, если cancelButtonClick потока не будет излучать значение для 10 секунд

Пробные:

final DateTime[] lastCancelDate = new DateTime[1]; 
cancelButtonClick 
     .map(new Func1<Void, DateTime>() { 
      @Override 
      public DateTime call(Void aVoid) { 
       return DateTime.now(); 
      } 
     }) 
     .subscribe(new Action1<DateTime>() { 
      @Override 
      public void call(DateTime dateTime) { 
       lastCancelDate[0] = dateTime; 
      } 
     }); 

actionButtonClick     
     .delay(10, TimeUnit.SECONDS) 
     .filter(new Func1<Void, Boolean>() { 
      @Override 
      public Boolean call(Void aVoid) { 
      return 
       lastCancelDate[0] == null 
       || (new Duration(lastCancelDate[0], DateTime.now()).getStandardSeconds()) 
        > 10; 
      } 
     }) 
     .doOnNext(new Action1<Void>() { 
      @Override 
      public void call(Void aVoid) { 
       lastCancelDate[0] = null; 
      } 
     }) 
     .subscribe(new Action1<Void>() { 
      @Override 
      public void call(Void aVoid) { 
       Log.d("ACTIONII", "Got Action"); 
      } 
     }); 

Это работает, но должен быть лучший способ.

ответ

0

Так вы хотите предотвратить actionButtonClick, чтобы испустить, если cancelButtonClick не испускает элемент в ближайшие 10 секунд?

Сначала вы могли бы немного улучшить свое решение с помощью BehaviorSubject:

BehaviorSubject<DateTime> lastCancelSubject = BehaviorSubject.create(); 

cancelButtonClick 
     .map(new Func1<Void, DateTime>() { 
      @Override 
      public DateTime call(Void aVoid) { 
       return DateTime.now(); 
      } 
     }) 
     .subscribe(lastCancelSubject); 

actionButtonClick 
     .delay(10, TimeUnit.SECONDS) 
     .filter(new Func1<Void, Boolean>() { 
      @Override 
      public Boolean call(Void aVoid) { 
       return 
         lastCancelDate[0] == null 
           || (new Duration(lastCancelSubject.getValue(), DateTime.now()).getStandardSeconds()) 
           > 10; 
      } 
     }) 
     .subscribe(new Action1<Void>() { 
      @Override 
      public void call(Void aVoid) { 
       Log.d("ACTIONII", "Got Action"); 
      } 
     }); 

Хотя ой-ява предлагает severals путь для достижения этой цели, я бы объявить еще Observable:

final Observable<Boolean> iscancelledObservable = cancelButtonClick 
     .buffer(10, TimeUnit.SECONDS) 
     .first() 
     .map(new Func1<List<Void>, Boolean>() { 
      @Override 
      public Boolean call(List<Void> voids) { 
       return voids.size() > 0; 
      } 
     }); 

actionButtonClick 
     .flatMap(new Func1<Void, Observable<Boolean>>() { 
      @Override 
      public Observable<Boolean> call(Void aVoid) { 
       return iscancelledObservable; 
      } 
     }) 
     .filter(new Func1<Boolean, Boolean>() { 
      @Override 
      public Boolean call(Boolean aBoolean) { 
       return !aBoolean; 
      } 
     }) 
     .subscribe(new Action1<Void>() { 
      @Override 
      public void call(Void aVoid) { 
       Log.d("ACTIONII", "Got Action"); 
      } 
     }); 

Этого решение более функциональна и не зависит от состояния хранения.

+0

Спасибо за ваши усилия. клик actionButton не должен испускать значение **, если cancelButton strem ВЫИГРЫВАЕТ значение в NEXT 10 секунд ** – tchelidze

+0

Обновил мой ответ соответственно –