【问题标题】:RxJava flatmap: How to make multiple calls based on result from first callRxJava flatmap:如何根据第一次调用的结果进行多次调用
【发布时间】:2017-02-16 14:47:14
【问题描述】:

我有 2 个改装电话需要进行 A 和 B:

(A):返回一个数组列表

(B):获取 (A) 的结果,它是一个 ArrayList。 (B) 遍历 ArrayList 并使用 each 进行改造调用,并将生成的数据组合成最终的 ArrayList,该 ArrayList 将发送给我的订阅者 onNext()

我在获取语法正确时遇到了麻烦....例如,我试图返回 arAllMedia,但我下面的代码希望我返回一个 Observable。

ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken())
                .flatMap(new Func1<UserSelfFollows, Observable<? extends ArrayList<Media.MediaData>>>() {
                    @Override
                    public Observable<? extends ArrayList<Media.MediaData>> call(UserSelfFollows userSelfFollows) {

                        //make second requests based on response from First request to get all Users
                        ArrayList<Media.MediaData> arAllMedia = new ArrayList<>();
                        for(UserSelfFollows.UserDataFollows user : userSelfFollows.userdata){

                            Response <ResponseBody> response ;
                            Call <ResponseBody> call;
                            try {
                                call = ServiceFactory.createRetrofitService().getMediaOfUser(user.id,sessionMgr.getAuthToken());
                                response =  call.execute();
                            }catch(IOException ex){
                                return Observable.error(ex);
                            }

                            if (response.isSuccessful()) {

                                try {
                                    String str = responseHelper.streamToString( response.body().byteStream());
                                    Gson gson = new GsonBuilder().create();
                                    Media media = gson.fromJson(str, Media.class);

                                    arAllMedia.addAll(media.mediaData);

                                } catch (IOException e) {
                                    return Observable.error(e);
                                }
                            } else {
                                return Observable.error( new Exception(  responseHelper.getErrorString( response.errorBody().byteStream())) );
                            }
                        }
                        return Observable.just(arAllMedia);

                    }
                })
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<ArrayList<Media.MediaData>>() {
                    @Override
                    public final void onCompleted() {

                    }

                    @Override
                    public final void onError(Throwable e) {

                    }

                    @Override
                    public final void onNext(ArrayList<Media.MediaData> arMedia) {

                    }
                })

使用下面的 Maxim 建议,但它不会编译:

ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken())
                .flatMapIterable(new Func1<UserSelfFollows, Iterable<?>>() {
                    @Override
                    public Iterable<?> call(UserSelfFollows userSelfFollows) {
                        return userSelfFollows.userdata;
                    }
                })
                .concatMap(new Func1<UserSelfFollows.UserDataFollows, Observable<Media.MediaData>>() {
                    @Override
                    public Observable<Media.MediaData> call(UserSelfFollows.UserDataFollows user) {

                        return ServiceFactory.createRetrofitService().getMediaOfUser(user.id,sessionMgr.getAuthToken());
                    }
                });

【问题讨论】:

    标签: android rx-java retrofit2


    【解决方案1】:

    你需要退货

    Observable.just(arAllMedia)
    

    【讨论】:

      【解决方案2】:

      您可以使用flatMapIterable 展平您的List,然后使用concatMap 按顺序触发请求,然后使用toList 运算符将结果收集回List

      ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken()
          .flatMapIterable(userSelfFollows -> userSelfFollows.userdata)
          .concatMap(user -> /*get & parse media; must return Observable<Media.MediaData>*/)
          .toList()
          ...
      

      【讨论】:

      • 我确实让它工作了,我在上面编辑了我的答案以准确显示我正在实现的目标,但似乎我的循环可以更优雅地完成。您可以使用我的代码应用您的上述建议吗?
      • 我已经更新了我的答案,其余的实现取决于你
      • 谢谢,但我无法应用您的建议,而且几乎没有关于如何执行此操作的示例。
      • 您可以将您的第二个 API 调用封装到 Observable 中(就像您对第一个请求所做的那样),然后使用 Observable.fromCallable 封装 parse 方法,并使用 flatMap 组合它。最终,您将获得Observable&lt;Media.MediaData&gt;。有很多示例如何实现这一目标。
      • 我用我目前所拥有的内容编辑了我的问题,但它不会编译也许你可以告诉我它有什么问题
      猜你喜欢
      • 1970-01-01
      • 2015-08-15
      • 2021-03-22
      • 1970-01-01
      • 2018-06-29
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多