当前位置: 首页 > 知识库问答 >
问题:

改造2个RxJava,将类似请求干净地链接在一起

弘承运
2023-03-14

球门

在我的应用程序中,我希望使用改装2上传一些文件到我的网络服务器(一次多个,在这种情况下是图片。)到那个特定的文件。

尝试

我对使用函数式编程范式不熟悉,所以我的理解可能会被误导。我有两个不同的对象,一个文件响应(DTO表示从我的网络服务器上传文件后的响应)和一个照片对象。这个Photo对象有两个字段,并充当在我的后端服务器中持久化的实体。它的字段对应于列,并且单独上传这些对象可以很好地工作。我想做的是一次扫描完成双重操作。

以下是我尝试过的:

List<Observable<FileResponse>> mObservables = new ArrayList<>(3);

...
...

Observable.merge(mObservables).
            map(new Func1<FileResponse, Observable<Photo>>() {
                @Override
                public Observable<Photo> call(FileResponse fileResponse) {
                    Photo photo = new Photo();
                    photo.setPath(fileResponse.getUrl());
                    photo.setId("demo123");
                    return mPhotoService.createPhoto(photo);
                }
            }).forEach(
                new Action1<Observable<Photo>>() {
                    @Override
                    public void call(Observable<Photo> photoObservable) {

                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        Log.e(TAG, "Error: " + throwable.getMessage());
                    }
                }
            );

以下是我的逻辑:

合并( ) — 将多个观测值合并为一个。

我希望我创建的观察对象列表合并在一起,这样我就可以对它们中的每一个执行相同的操作。在这种情况下,可观察对象的类型为FileResponse。这是到文件web服务的上载。

map()-通过对每个项应用函数来转换可观察项发出的项。

在本例中,我想对FileResponse Observable应用一个函数,该函数返回一个新的Observable,Observable。

弗雷奇( ) — 对可观察对象发出的每个项调用函数;阻塞,直到可观察对象完成。

然后,这将获取每个发出的可观察对象并上传它。但在这种情况下,这部分失败了。文件已成功上载,但forEach部分仅返回“Error:null”。

问题

这种理解是否接近我正在努力实现的目标?同样,我只是希望将多个请求链接在一起,当其他请求成功时执行新的请求。有没有更好/正确的方法来做这件事?

编辑注:

我忘了提一下,我可以像这样实现我想要的:

Observable.merge(mObservables)
            .map(new Func1<FileResponse, Observable<Photo>>() {
                @Override
                public Observable<Photo> call(FileResponse fileResponse) {
                    Photo photo = new Photo();
                    photo.setPath(fileResponse.getUrl());
                    photo.setDogId("123");
                    return mPhotoService.createPhoto(photo);
                }
            })
           .subscribe(new Subscriber<Observable<Photo>>() {
                    @Override
                    public void onCompleted() {
                        Log.d(TAG, "Save complete!");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "Error: " + e.getMessage());
                    }

                    @Override
                    public void onNext(Observable<Photo> photoObservable) {
                        photoObservable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
                                .subscribe(new Subscriber<Photo>() {
                                    @Override
                                    public void onCompleted() {
                                        Log.d(TAG, "Here!");
                                    }

                                    @Override
                                    public void onError(Throwable e) {
                                        Log.d(TAG, "Error! " + e.getMessage());
                                    }

                                    @Override
                                    public void onNext(Photo photo) {
                                        Log.d(TAG, "Woo!!");
                                    }
                                });
                    }
                }
            );

但我试图找到一种可能更干净的方法。如果这是唯一的办法,那就很公平了。只是想得到更多关于我在想什么的意见,看看我能做些什么使它看起来更好(或最佳实践)。

共有1个答案

司寇阳朔
2023-03-14

要使其更干净(并避免对onNext中的项目进行额外订阅),您可以将map()切换为flatMap()

java prettyprint-override">Observable.merge(mObservables)
                .flatMap(new Func1<FileResponse, Observable<Photo>>() {
                    @Override
                    public Observable<Photo> call(FileResponse fileResponse) {
                        Photo photo = new Photo();
                        return mPhotoService.createPhoto(photo);
                    }
                })
                .forEach(new Action1<Photo>() {
                    @Override
                    public void call(Photo photo) {

                    }
                });

正如您在代码片断中看到的,在平面地图之后的下一个运算符将看到Photo对象(与可观察对象进行比较)

 类似资料:
  • 第一个API调用返回一个元素列表,然后我想随后调用另一个API,在第一个API调用的列表的每个元素中返回一个。我(想我)已经得到了它,所以它用列表的每个元素调用第二个应用编程接口调用,但是我不确定如何订阅它来获得第二个调用返回的结果。 改装接口: 我不确定从这里去哪里。 我相信然后使我能够获得可观察的

  • 我正在尝试从使用普通改型迁移到使用RxJava扩展进行改型,以便在后台线程上进行API调用链。 例如,我有一个名为ModelGroup的对象,它有一个ModelPerson对象列表。我的目标是做到以下几点。 将ModelGroup发送到服务器并接收一个响应,它是一个整数,表示新插入的ID,我们称之为newGroupId 对于ModelGroup中的每个ModelPerson,设置Person。gr

  • 如果我没有使用lambda函数,这看起来就像普通的嵌套调用一样难看。这样做更好吗?

  • 所以基本上我想做的是,打第一个网络电话。如果调用的RESTful web服务返回1,则进行第二次网络调用。如果web服务返回0,则不要进行第二次网络调用。 这是我的密码 显然,上面的代码是错误的,因为它应该总是返回可观察的。那么,如果第一次网络调用返回0,我的代码应该如何编写?

  • 我在使用Reformation的RxJava支持链接观察对象时遇到了问题。我可能误解了如何使用它,否则它可能是改装中的一个bug。希望这里有人能帮我理解发生了什么事。编辑:我正在对这些响应使用MockRestaAdapter—这可能与RxSupport实现略有不同有关。 这是一个假的银行应用程序。它正在尝试进行传输,传输完成后,它应该执行帐户请求以更新帐户值。这基本上只是我试用flatMap的一个

  • 问题内容: 一般而言,我对RXJava相对较新(真的只是开始将其与RXJava2一起使用),而且我能找到的大多数文档都倾向于RXJava1。我现在通常可以在两者之间进行翻译,但是整个Reactive的内容是如此之大,以至于它是一个压倒性的API,具有很好的文档(当您可以找到它时)。我正在尝试简化我的代码,这是我想用婴儿的脚步做到的。我要解决的第一个问题是我在当前项目中做的很多工作: 您有一个请求,