Множественные действия или неконструктивное использование типов реакторов - PullRequest
1 голос
/ 29 апреля 2019

Я пытаюсь разобраться в Spring Boot и Reactors (я был далеко от Java почти два десятилетия).Ресурс, на котором я учусь, дает слишком простые примеры, и ни один поиск не возвращает какую-либо значимую информацию: только запутанная документация, которая ничего не отвечает.

Я пытаюсь достичь - по крайней мере в принципе -очень просто.

У меня есть функция для удаления изображения, хранящегося в UPLOAD_ROOT.При загрузке изображение имело name и ему было присвоено id.Затем это изображение было сохранено как image.id + "-" + image.name (что позволяет загружать несколько изображений с одним и тем же исходным именем файла).Класс Image обеспечивает ассоциацию значений id и name, которые хранятся в 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>.и возвращает тот же Mono<Image>, чтобы можно было сделать больше.Но я не могу найти ссылки на что-либо, что позволяет это сделать.

Как мне заставить все вложенные функции выполняться на самом деле?(Я пробовал разные вещи с .then() и .subscribe() в конце каждого, но ничего не давало последовательных и полностью функциональных результатов.) Или есть какая-то секретная функция, которая позволит мне выполнять нетрансформирующую цепочку?

1 Ответ

0 голосов
/ 08 мая 2019

Что-то не так с использованием 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);
    }
  })
}
...