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

使用RxJava改造为列表中的每个项目发出API请求

满博
2023-03-14

我试图通过将多个改型api调用链接在一起来创建一个可观察的api。这些步骤是:

  1. 使用api调用获取json对象列表
  2. 对于列表中的每个对象,进行另一个api调用以获取有关该项目的更多详细信息
  3. 将从这个新的详细对象中获取的数据写入磁盘上的文件(列表中的每个项目都会出现这种情况)
  4. 最后返回一个单独对象的可观察性,该对象要求为之前的每个对象创建一个文件

这是我到目前为止所拥有的:

public static Observable<DownloadedFiles> downloadFiles() {
    DownloadedFiles downloadedFiles = new DownloadedFiles();
    Observable.create(subscriber -> {
        return getRestService().getObjectList()
        .flatMapIterable(objects -> objects)
        .flatMap(objectLimited -> getRestService().getObject(objectLimited.getPath()))
        .doOnNext(objectFull -> {

            try {
                File file = new File();
                // Extract data from objectFull and write new file to disk
                // ...
                } catch (IOException e) {
                subscriber.onError(e);
            }

            downloadedFiles.putFile(file);
        })
        .toList()
        .map(objects -> downloadedFiles)
        .finallyDo(() -> {
            subscriber.onNext(downloadedFiles);
            subscriber.onCompleted();
        });
    });
}

@GET("/api/...")
Observable<List<Object>> getObjectList();

@GET("/api/.../{path}")
Observable<Object> getObject(@Path("path") String path);

请有人确认我使用了正确的运算符。谢谢

共有2个答案

柴坚诚
2023-03-14

我想像这样的应该适合你。您可以使用REST服务中的Observable映射到每个下载的文件,而不必拉入主题以将其发送到下载的文件:

public static Observable<DownloadedFile> downloadFiles() {
    final Observable<Observable<FullObject>> observable =  getRestService().getObjectList()
            .flatMapIterable(objects -> objects)
            .map(objectLimited -> getRestService().getObject(objectLimited.getPath()));

    return  Observable.mergeDelayError(observable)
            .map(fullObject -> {
                try {
                    File file = new File("path");
                    // Extract data from objectFull and write new file to disk
                    // ...

                    return new DownloadedFile();
                } catch (IOException e) {
                    throw OnErrorThrowable.from(OnErrorThrowable.addValueAsLastCause(e, fullObject));
                }
            });
}

如果您想在传播任何错误之前发出成功保存的文件,您可能需要考虑使用mergeDelayError(map())而不是平面地图。

韦鸣
2023-03-14

编辑:删除可观察的。创造,改造已经使你可以观察到,你只需要改变它。

编辑2:您也不需要对subscriber.on错误做任何事情,如果抛出一个错误,它会自己调用subscriber.on错误。

很好,不知道为什么你去与平面图观察。我宁愿做平面地图观察e::fROM,也收集值得添加。基本上,我要把一件事映射到许多件事上,然后做一些动作,把许多件事收集回一件事上,然后在收集完所有发射的物品后订阅那件事。

public static Observable<DownloadedFiles> downloadFiles() {        
        return getRestService().getObjectList()
        .flatMap(Observable::from)
        .flatMap(objectLimited -> getRestService().getObject(objectLimited.getPath()))
        .doOnNext(objectFull -> {
            try {
                File file = new File();
                // Extract data from objectFull and write new file to disk
                // ...
            } catch (IOException e) {
                new IOException(e);
            }})
      .collect(() -> new DownloadFiles<>(), (files, object) -> {  files.add(object});
 类似资料:
  • 我有一个方法返回一个

  • 我在玩RXJava,在Android系统中改装。我正在努力实现以下目标: 我需要定期调查一个电话,给我一个可观察的 一旦我得到这个列表,我想在每个交付迭代,并调用另一个方法,将给我的ETA(所以只是更多的信息)我想把这个新的信息附加到交付中,并返回完整的列表与附加到每个额外的信息项目。 一旦我得到了列表,我知道在没有rxjava的情况下如何做到这一点,但我想练习一下。 这是我目前的代码: 这是给我

  • 问题内容: 我正在努力实现我认为在Rx中相当简单的东西。 我有一个项目列表,我想延迟每个项目的发出。 似乎Rx delay()运算符只是将所有项目的发射偏移指定的延迟,而不是每个单独的项目。 这是一些测试代码。它将列表中的项目分组。然后,每个组应在发出之前应用延迟。 结果是: 但是我希望看到的是这样的: 我究竟做错了什么? 问题答案: 一种方法是将可观察值与可观察值结合起来以延迟输出。

  • 我使用改型2,我正在学习RxJava。我从某处下载了一个项目列表。我想对每个项目进行api调用,并创建扩展项目的新列表。两个调用都返回一个可观察的。它看起来像这样: 详细服务: } 问题是get细节返回一个可观察的,我不能用它来构造扩展项。在rxJava链中,更改get细节调用以返回对象不起作用,我猜是因为它将结果返回给主线程。如何获取对象本身?我尝试了很多其他的方法,但到目前为止都没有成功。

  • 我用改型/rxJava调用我的API,得到了一个可观察的响应,就像一个BreedDog列表 ...你可以看到我的代码: 这是可行的,但是现在,对于列表中的每一项,我都需要调用API来获取URL图像并更新列表。。但我不知道怎么。。。我试着在Observable中更改我的单个响应,并使用了flatMap或flatMapIterate之类的运算符。。等等,但每次我都会在对象上出错。。没有一个例子。。。等

  • 我正在使用改造从REST服务获取数据。在接收json(对象列表)后,我想为列表上的每个位置获取位图。最好的方法是什么?我试图在改造后创建的可观察对象上使用地图/平面地图,但它不起作用(或者,可能是我做错了)。 改造接口方法: 使用方法: 当我试图使用平板地图()或地图()时,它总是返回一个列表,但我需要每个项目单独。 任何帮助都将不胜感激!