问题描述
我有2个改造电话,需要进行A和B:
(一):返回一个ArrayList
(B):获取(A)的结果,它是一个ArrayList。 (B)遍历ArrayList并使用每个数组进行改造调用,并将结果数据合并到最终ArrayList中,该ArrayList发送给我的订户onNext()
我能够使其与Flatmap一起使用,但是解决方案不是很好。 据我了解,更好的解决方案是将flatMapIterable与concatMap一起使用,但是我似乎无法采用对concatMap进行flatMapIterable的工作。
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) {
                    }
                })
这是我到目前为止的内容,但是无法编译:
ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken())
            .flatMapIterable(new Func1<UserSelfFollows, Iterable<?>>() {
                @Override
                public Iterable<?> call(UserSelfFollows userSelfFollows) {
                    return userSelfFollows.userdata;
                }
            })
            .<Media.MediaData>flatMap(new Func1<UserSelfFollows.UserDataFollows, Observable<Media.MediaData>>() {
                @Override
                public Observable<Media.MediaData> call(UserSelfFollows.UserDataFollows user) {
                    return ServiceFactory.createRetrofitService().getMediaOfUser(user.id, sessionMgr.getAuthToken());
                }
            })
            .toList();
错误是:
1楼
 
     如果我理解正确的情况下,你可以使用flatMapIterable ,然后flatMap运营商,在最后收集所有的改造与调用导致toList 。 
 
     在第一个flatMapIterable您将从第一个调用( getUserFollowing() )获得的UserDataFollows List展平到一个Obsevrable,该Obsevrable会从该List中发出多个项目,然后flatMap创建一个Observable ,该Observable UserSelfFollows.UserDataFollows每个UserSelfFollows.UserDataFollows数据对象进行改造,(它会并行发生,这似乎更适合这里,但是如果您对顺序执行感兴趣,也可以使用concatMap ),然后将所有最终数据收集在一起,作为MediaData对象的列表,可以使用toList 
ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken())
            .flatMapIterable(new Func1<UserSelfFollows, Iterable<?>>() {
                @Override
                public Iterable<?> call(UserSelfFollows userSelfFollows) {
                    return userSelfFollows.userdata;
                }
            })
            .flatMap(new Func1<UserSelfFollows, Observable<Media>>() {
                @Override
                public Observable<Media> call(UserSelfFollows user) {
                    return ServiceFactory.createRetrofitService().getMediaOfUser(user.id, sessionMgr.getAuthToken());
                }
            })
            .toList()
            .subscribe(new Action1<List<Media>>() {
                @Override
                public void call(List<Media> rs) {
                    //do something with the list of media data
                }
            });
2楼
 
     我从未同时使用flatMapIterable或concatMap ,但是作为替代解决方案,您可以使用flatMap和compose运算符: 
ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken())
   .flatMap(list -> Observable.from(list))
   .compose(getComposer())
   .subscribe(mediaData -> mMediaDataList.add(mediaData), throwable -> {}, () -> { // on complete do something with mMediaList});
 
     其中getComposer()返回Transformer UserSelfFollows > Media.MediaData 
protected Observable.Transformer<UserSelfFollows, Media.MediaData> getComposer() {
    return  ;
}
3楼
Yosriz的回答使我朝着正确的方向前进。 因此,为了避免其他人为此而烦恼,这里是完整的代码解决方案:
ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken())
                .flatMapIterable(new Func1<UserSelfFollows, Iterable<UserSelfFollows.UserDataFollows>>() {
                    @Override
                    public Iterable< UserSelfFollows.UserDataFollows > call(UserSelfFollows userSelfFollows) {
                        return userSelfFollows.userdata;
                    }
                })
                .flatMap(new Func1<UserSelfFollows.UserDataFollows, Observable<Media>>() {
                    @Override
                    public Observable<Media> call(UserSelfFollows.UserDataFollows user) {
                        return ServiceFactory.createRetrofitService().getMediaOfUser(user.id, sessionMgr.getAuthToken());
                    }
                })
                .toList()
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<List<Media>>() {
                    @Override
                    public final void onCompleted() {
                    }
                    @Override
                    public final void onError(Throwable e) {
                        userMessageHandler.showDialog(mParentActivity, mParentActivity.getString(R.string.error_retrieving_data_title),
                                mParentActivity.getString(R.string.error_self_following_media) + e.getMessage(), 0);
                    }
                    @Override
                    public final void onNext(List<Media> arMedia) {
                        if (arMedia.size() == 0)
                            userMessageHandler.showToast(mParentActivity, mParentActivity.getString(R.string.warn_no_following));
                        else {
                            ArrayList<Media.MediaData> allMedia = new ArrayList<>();
                            for(Media media : arMedia){
                                allMedia.addAll(media.mediaData);
                            }
                            mBinding.gridview.setAdapter(new MediaGridViewAdapter(mParentActivity,FollowingViewModel.this, allMedia));
                        }
                    }
                });