对反应堆类型的多种动作或非变换性使用

时间:2019-04-29 12:17:32

标签: java spring reactor

我正在努力使自己了解Spring Boot和Reactors(已经离开Java近二十年了)。我正在从中学习的资源给出了过于基本的示例,并且没有搜索返回任何有意义的信息:只有复杂的文档无法解决任何问题。

我想要实现的目标-至少在原则上-非常简单。

我具有删除UPLOAD_ROOT中存储的图像的功能。上载时,图像具有name,并被分配了id。然后将该图像存储为image.id + "-" + image.name,(允许上传具有相同源文件名的多个图像)。 Image类提供idname值的关联,并将它们存储在MongoDB中。

通过Image访问数据库public interface ImageRepository extends ReactiveCrudRepository <Image, String>

通过id进行删除。此刻我的代码(源自一个按文件名删除的版本,并且没有处理名称冲突):

public Mono<Void> deleteImage(String fileId) {
    return Mono.fromRunnable(() -> {
        imageRepository.findById(fileId)
                .map(image -> {
                    Mono<Void> deleteFile = Mono.fromRunnable(() -> {
                        try {
                            Files.deleteIfExists(Paths.get(UPLOAD_ROOT, image.getId() + "-" + image.getName()));
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    });
                    Mono<Void> deleteRecord = Mono.fromRunnable(() -> {
                        imageRepository.delete(image);
                    });
                    return Mono.when(deleteFile, deleteRecord).then();
                });
    }).then();
}

问题在于,包裹在imageRepository.findById(fileId).map(image -> { ... });中的deleteFile和deleteRecord永远不会发生。也没有Mono.when()

对我来说更有意义的另一种方法是对.map使用非转换性的替代函数,对提供的Mono<Image>的元素进行操作并返回相同的{ {1}},以便可以做更多的事情。但是我找不到任何能使之实现的参考。

如何使所有嵌套函数真正发生? (我在Mono<Image>.then()的最后都尝试了各种方法,但没有得到一致且完全有效的结果。)或者是否有一些秘密功能可以让我执行非转化链?

1 个答案:

答案 0 :(得分:0)

使用Mono.fromRunnable有点问题。 尝试以下代码:

public Mono<Void> deleteImage(String fileId) {
  return imageRepository.findById(fileId)
           .flatMap(image -> Mono.when(deleteFile(image), deleteRecord(image)).then());
}

private Mono<Void> deleteRecord(Image image) {
  return imageRepository.delete(image);
}

private Mono<Void> deleteFile(Image image) {
  return Mono.fromRunnable(() -> {
    try {
      Files.deleteIfExists(Paths.get(UPLOAD_ROOT, image.getId() + "-" + image.getName()));
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  })
}