我们说我有两个Observable
s:
obs1
在搜索框中发出用户输入结果,
obs2
将字符串作为输入并启动HTTP请求,然后提供结果
现在,我想限制HTTP请求的数量不是一些恒定的时间间隔,而是取决于当前请求obs2
完成的时间,如下所示:
t
,obs2
会立即使用t
te
,obs2
仍然是#34;忙碌",没有任何反应tes
,obs2
仍然是#34;忙碌",没有任何反应test
,obs2
仍然是#34;忙碌",没有任何反应t
- HTTP响应已经到达,obs2
现在是#34;免费",它查看obs1
上次发布的值并找到test
,开始新请求test
- HTTP响应已经到达,obs2
现在是#34;免费",它查看obs1
上次发布的值并找到test
,没有,因为价值没有改变。我可以通过引入额外的变量来表明系统的状态和搜索查询累加器,但我想知道这是否可以用纯函数方式完成,即仅使用rxJava
方法?
答案 0 :(得分:1)
查看代码和评论。
import rx.Observable;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
import xdean.jex.extra.Pair;
public class Q43975663 {
public static void main(String[] args) throws InterruptedException {
PublishSubject<String> textSub = PublishSubject.create(); // emit user input text
PublishSubject<String> taskSub = PublishSubject.create(); // emit when execution thread is free
// core
Observable
// when new text input or execution thread change to free, emit an item
.combineLatest(textSub.distinctUntilChanged(), taskSub, Pair::of)
// if the text not change or task cycle not change, ignore it
.scan((p1, p2) ->
(p1.getLeft().equals(p2.getLeft()) || p1.getRight().equals(p2.getRight())) ?
p1 : p2)
.distinctUntilChanged()
// map to user input text
.map(Pair::getLeft)
// scheduler to IO thread
.observeOn(Schedulers.io())
// do HTTP request
.doOnNext(Q43975663::httpTask)
// emit item to notify the execution thread is free
.doOnNext(taskSub::onNext)
.subscribe();
// test
taskSub.onNext("start");
textSub.onNext("t");
textSub.onNext("te");
textSub.onNext("tex");
textSub.onNext("text");
Thread.sleep(5000);
textSub.onNext("new");
textSub.onNext("new");
textSub.onNext("text");
Thread.sleep(5000);
}
static void httpTask(String id) {
System.out.printf("%s \tstart on \t%s\n", id, Thread.currentThread());
try {
Thread.sleep((long) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s \tdone on \t%s\n", id, Thread.currentThread());
}
}
注意Pair
是一个简单的类,有两个值,左和右。
输出:
t start on Thread[RxIoScheduler-2,5,main]
t done on Thread[RxIoScheduler-2,5,main]
text start on Thread[RxIoScheduler-2,5,main]
text done on Thread[RxIoScheduler-2,5,main]
new start on Thread[RxIoScheduler-2,5,main]
new done on Thread[RxIoScheduler-2,5,main]
text start on Thread[RxIoScheduler-2,5,main]
text done on Thread[RxIoScheduler-2,5,main]