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]