RxJava2对2个订户执行http请求的一个Observable链运行请求两次

时间:2018-06-03 16:04:28

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

我正在尝试理解反应式编程背后的概念,目前我正在做一个JavaFX应用程序,在http请求之后加载3个随机github用户。 我创建了一个Observable,它包含对github api的调用(api返回30个元素的列表),并且从响应中我想提取前3个元素以将它们放在页面中。

 Observable<List<GitHubUser>> loadButtonObservable = JavaFxObservable
            .actionEventsOf(runButton)
            .flatMap(ae -> 
              Observable.fromCallable(() ->
                githubExternalService.getUsersSince(
                  new Random().nextInt(500))));

 loadButtonObservable
   .take(1)
   .map(list -> list.get(0))
   .subscribe(i -> userOneVBox.getChildren().add(createText(i)));
 loadButtonObservable
   .skip(1)
   .take(1)
   .map(list -> list.get(0))
   .subscribe(i -> userTwoVBox.getChildren().add(createText(i)));
 loadButtonObservable
   .skip(2)
   .take(1)
   .map(list -> list.get(0))
   .subscribe(i -> userThreeVBox.getChildren().add(createText(i)));

我希望当单击按钮时,会发出请求并且订阅者会收到30个元素的列表,而是从每个订阅者运行整个可观察链。 你能帮我理解如何构造代码,这样它就可以做1个请求而不是3个吗?

2 个答案:

答案 0 :(得分:0)

每个订阅包括任何订阅副作用,例如延迟可调用。我不确定RxJava语法,但是在Rx.net中,使用.Publsh可以避免这种情况,它会将值多播到订阅者而不是可观察的。

答案 1 :(得分:0)

是的,我已经从rx读过PublishSubject,在这种情况下它可能会有所帮助。 与此同时,我采用了不同的方法,我将在此发布。 任何代码审查都表示赞赏。

JavaFxObservable.actionEventsOf(loadUsersButton)
                .flatMap(ae -> Subject.fromCallable(() -> githubExternalService.getUsersSince(new Random().nextInt(500))))
                .flatMapIterable(x -> x)
                .take(3)
                .map(this::createText)
                .map(text -> {
                    VBox vBox = new VBox();
                    vBox.getChildren().add(text);
                    return vBox;
                }).subscribe(vbox -> githubInfo.getChildren().add(vbox));