热(ish)可观察

时间:2018-03-05 13:53:58

标签: java rx-java reactive-programming rx-java2

我需要在冷热Observable之间有一些东西。它应该在客户端订阅时发出项目,并在客户端取消订阅时停止发送。但是当客户订阅相同的Observable时,应该交付剩余的项目。最后一件事就是项目之间的时间。

Observable<String> hotishObservable = createHotishObservable("a", "b", "c");
Disposable sub = hotishObservable.subscribe();
// emit "a"
// 1 second passed
// emit "b"
sub.dispose()
Disposable sub = hotishObservable.subscribe();
// emit "c"

显而易见的解决方案是扩展ObservableOnSubscribe并处理ObservableEmitter

class HotishSub implements ObservableOnSubscribe<String> {

    public HotishSub(String... items) {
        this.items = items;
    }

    @Override
    public void subscribe(ObservableEmitter<String> emitter) {
        if(isNotEmpty())
            emitter.onNext(nextItem);
            executor.schedule(this::handleNext, 1000, TimeUnit.MILLISECONDS);
        else
            emitter.onComplete();
    }

    private void handleNext(){
        //if emitter is not disposed and there're still items then emit it
    }
}

Observable<String> createHotishObservable(String... items){
  return Observable.create(new HotishSub(items));
}

还有更好的选择吗?

需要来自简化聊天机器人的消息流。 UI客户端代码使用相同的Observable来获取来自机器人和真实用户的消息流。

1 个答案:

答案 0 :(得分:0)

我使用 public static <T> Flowable<T> create(T... ts) { List<T> list = new ArrayList<>(Arrays.asList(ts)); return Flowable.generate(() -> list, (l, e) -> { if (l.isEmpty()) { e.onComplete(); } else { e.onNext(l.remove(0)); if (!l.isEmpty()) { try { Thread.sleep(1000); } catch (InterruptedException ex) { // you can use other way to delay it } } } }); } 来执行此操作。

  public static void main(String[] args) throws Exception {
    Flowable<String> ob = create("a", "b", "c", "d", "e");
    Disposable d = ob.subscribeOn(Schedulers.computation())
        .subscribe(i -> System.out.println(System.currentTimeMillis() + "\t" + i));
    Thread.sleep(2500);
    d.dispose();
    ob.subscribeOn(Schedulers.computation())
        .blockingSubscribe(i -> System.err.println(System.currentTimeMillis() + "\t" + i));
  }

然后测试

1520304164412   a // sys.out
1520304165413   b // sys.out
1520304166413   c // sys.out
1520304166928   d // sys.err
1520304167927   e // sys.err

输出:

{{1}}