rxjava interval() 在某些事件后重置时间
rxjava interval() reset time after some event
我正在用 RxJava 制作一个 Android 应用程序,在其中一个页面中,我有一个按钮,当按下时,页面会刷新。如果用户在此期间没有按下按钮,我还希望每 10 秒自动刷新一次。但是当用户单击按钮时,我希望自动刷新操作在单击后 10 秒后发生。而不是继续其自己的 10 秒间隔。
例如,在第 0 秒,应用程序进行自动刷新,然后在第 3 秒,用户按下按钮。然后自动刷新应该发生在第 13 秒、第 23 秒等。
我知道有一个 interval()
运算符会以一定的时间间隔发出项目。不过好像没办法"reset"开始时间。它有点像取消订阅并再次订阅 interval()
Observable。一段代码就像
Observable<Long> intervalObservable = Observable.inteval(10, TimeUnit.SECONDS)
RxView.click(refreshButton).map(ignored -> 0L)
.merge(intervalObservable)
.subscibe(ignore -> performRefresh());
如果有办法 "unmerge" 和 intervalObservable
,那么我可以在 onNext
中取消合并,然后再次合并。但是好像没有。
我怎样才能做到这一点?
最简单的解决方案不是每次单击按钮时都取消订阅旧的 Observable 并再次订阅吗?
Subscription subscription= null;
Observable<Long> interval = nul;
public void subscribe(){
interval = Observable
.interval(10000L, TimeUnit.MILLISECONDS);
subscription = interval.subscribe(item -> System.out.println("doing something"));
}
public void eventClick(){
if(clickButtin){
subscription.unsubscribe();
subscribe();
}
}
您可以使用 switchMap
运算符很好地完成此操作。每次按下按钮时,它都会 切换 到间隔可观察对象的新订阅 - 这意味着它将重新开始。之前的订阅会自动删除,因此不会有多个间隔 运行.
Observable<Long> intervalObservable = Observable.interval(10, TimeUnit.SECONDS);
RxView.clicks(refreshButton)
.switchMap(ignored -> {
return intervalObservable
.startWith(0L) // For an immediate refresh
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(x -> performRefresh());
})
.subscribe();
startWith
向间隔添加一个立即值(单击按钮时立即刷新),observeOn
确保刷新发生在主线程上(这很重要,因为interval 将在后台线程上发出)。
Update:vman注意到这个实现只有在用户第一次点击按钮后才开始刷新。以下选项将在订阅后立即刷新,然后每 10 秒刷新一次,直到单击按钮 – 此时它将再次立即刷新,然后继续每 10 秒更新一次。
Observable<Long> intervalObservable = Observable.interval(10, TimeUnit.SECONDS)
.startWith(0L) // For an immediate refresh
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(x -> performRefresh());
Observable<Long> buttonClickedObservable = RxView.clicks(refreshButton)
.map(e -> 0L) // To make the compiler happy
.switchMap(ignored -> Observable.error(new RuntimeException("button pressed")));
Observable.merge(intervalObservable, buttonClickedObservable)
.retry()
.subscribe();
在这个实现中,一个进行刷新的 Observable 被立即订阅(导致立即刷新,并且每 10 秒重复一次),它与一个 Observable 合并,只要点击刷新按钮就会出错。最后的 retry
将导致整个事件在错误(单击按钮)时重新订阅 - 导致一切重新开始。
我正在用 RxJava 制作一个 Android 应用程序,在其中一个页面中,我有一个按钮,当按下时,页面会刷新。如果用户在此期间没有按下按钮,我还希望每 10 秒自动刷新一次。但是当用户单击按钮时,我希望自动刷新操作在单击后 10 秒后发生。而不是继续其自己的 10 秒间隔。
例如,在第 0 秒,应用程序进行自动刷新,然后在第 3 秒,用户按下按钮。然后自动刷新应该发生在第 13 秒、第 23 秒等。
我知道有一个 interval()
运算符会以一定的时间间隔发出项目。不过好像没办法"reset"开始时间。它有点像取消订阅并再次订阅 interval()
Observable。一段代码就像
Observable<Long> intervalObservable = Observable.inteval(10, TimeUnit.SECONDS)
RxView.click(refreshButton).map(ignored -> 0L)
.merge(intervalObservable)
.subscibe(ignore -> performRefresh());
如果有办法 "unmerge" 和 intervalObservable
,那么我可以在 onNext
中取消合并,然后再次合并。但是好像没有。
我怎样才能做到这一点?
最简单的解决方案不是每次单击按钮时都取消订阅旧的 Observable 并再次订阅吗?
Subscription subscription= null;
Observable<Long> interval = nul;
public void subscribe(){
interval = Observable
.interval(10000L, TimeUnit.MILLISECONDS);
subscription = interval.subscribe(item -> System.out.println("doing something"));
}
public void eventClick(){
if(clickButtin){
subscription.unsubscribe();
subscribe();
}
}
您可以使用 switchMap
运算符很好地完成此操作。每次按下按钮时,它都会 切换 到间隔可观察对象的新订阅 - 这意味着它将重新开始。之前的订阅会自动删除,因此不会有多个间隔 运行.
Observable<Long> intervalObservable = Observable.interval(10, TimeUnit.SECONDS);
RxView.clicks(refreshButton)
.switchMap(ignored -> {
return intervalObservable
.startWith(0L) // For an immediate refresh
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(x -> performRefresh());
})
.subscribe();
startWith
向间隔添加一个立即值(单击按钮时立即刷新),observeOn
确保刷新发生在主线程上(这很重要,因为interval 将在后台线程上发出)。
Update:vman注意到这个实现只有在用户第一次点击按钮后才开始刷新。以下选项将在订阅后立即刷新,然后每 10 秒刷新一次,直到单击按钮 – 此时它将再次立即刷新,然后继续每 10 秒更新一次。
Observable<Long> intervalObservable = Observable.interval(10, TimeUnit.SECONDS)
.startWith(0L) // For an immediate refresh
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(x -> performRefresh());
Observable<Long> buttonClickedObservable = RxView.clicks(refreshButton)
.map(e -> 0L) // To make the compiler happy
.switchMap(ignored -> Observable.error(new RuntimeException("button pressed")));
Observable.merge(intervalObservable, buttonClickedObservable)
.retry()
.subscribe();
在这个实现中,一个进行刷新的 Observable 被立即订阅(导致立即刷新,并且每 10 秒重复一次),它与一个 Observable 合并,只要点击刷新按钮就会出错。最后的 retry
将导致整个事件在错误(单击按钮)时重新订阅 - 导致一切重新开始。