Rx java 使用“Observable”实现速率受限的搜索结果
假设我有两个Rx java 使用“Observable”实现速率受限的搜索结果,rx-java,system.reactive,Rx Java,System.reactive,假设我有两个可观察的s: obs1在搜索框中发出用户输入的结果, obs2将字符串作为输入,启动HTTP请求,然后提供结果 现在,我想限制HTTP请求的数量,不是通过某个固定的时间间隔,而是取决于对当前请求执行obs2的时间,如下所示: 用户类型t,obs2立即使用t 用户类型te,obs2仍然“忙”,什么也没发生 用户类型tes,obs2仍然“忙”,什么也没发生 用户类型test,obs2仍然“忙”,什么也没发生 t-HTTP响应已经到达,obs2现在是“免费的”,它查看obs1最后发出的值并
可观察的s:
obs1
在搜索框中发出用户输入的结果,
obs2
将字符串作为输入,启动HTTP请求,然后提供结果
现在,我想限制HTTP请求的数量,不是通过某个固定的时间间隔,而是取决于对当前请求执行obs2
的时间,如下所示:
用户类型t
,obs2
立即使用t
用户类型te
,obs2
仍然“忙”,什么也没发生
用户类型tes
,obs2
仍然“忙”,什么也没发生
用户类型test
,obs2
仍然“忙”,什么也没发生
t
-HTTP响应已经到达,obs2
现在是“免费的”,它查看obs1
最后发出的值并找到test
,启动一个新的请求
test
-HTTP响应已经到达,obs2
现在是“免费的”,它查看obs1
最后发出的值并找到test
,因为值没有改变,所以不做任何操作
我可以通过引入额外的变量来表示系统状态和搜索查询累加器来实现这一点,但我想知道这是否可以通过纯粹的功能性方式实现,即仅使用rxJava
方法?参见代码和注释
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());
}
}
你知道这可能会导致将近2倍的延迟吗?发出多个web请求以避免最终用户的长时间延迟不是更好吗?
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]