簡體   English   中英

RxJava僅在其他源在一段時間內不提供項目的情況下才發出項目

[英]RxJava only emit item if another source will not item for some period

有兩個可觀察到的

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");
            }
        });

它有效,但是應該有更好的方法。

因此,如果cancelButtonClick在接下來的10秒鍾內不發射項目,您想阻止actionButtonClick發射嗎?

首先,您可以使用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");
            }
        });

盡管rx-java提供了Observable實現此目的的方法,但我還是要聲明另一個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");
            }
        });

此解決方案功能更強大,並且不依賴於存儲狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM