Получите ответ от CompletableFuture

#java #completable-future

Вопрос:

Я пытаюсь добавить Async в свою операцию извлечения из базы данных. Тем не менее, я застрял в попытках получить ответ от CompletableFuture.allOf() . Присоединяйтесь, верните «пустоту». Вместо этого, как я могу вернуть a List<QuestionResponseData> , как указано в коде. Ниже приведен мой код

 @RequestMapping(method = RequestMethod.POST, path = "/questionsByAssessmentIdAndQuestionNumber")
    public List<QuestionResponseData> getQuestionsByIdAndLimit(@RequestBody QuestionOptionRequest questionOptionRequest) {
        String assessmentId = questionOptionRequest.getAssessmentId();
        QuestionOptionRequest request = QuestionOptionRequest.builder().assessmentId(questionOptionRequest.getAssessmentId()).startingQuestion(1).build();
        CompletableFuture<List<QuestionResponseData>> questions = questionService.getQuestions(request);
        QuestionOptionRequest request1 = QuestionOptionRequest.builder().assessmentId(assessmentId).startingQuestion(26).build();
        CompletableFuture<List<QuestionResponseData>> questions1 = questionService.getQuestions(request1);
        QuestionOptionRequest request2 = QuestionOptionRequest.builder().assessmentId(assessmentId).startingQuestion(51).build();
        CompletableFuture<List<QuestionResponseData>> questions2 = questionService.getQuestions(request2);
        QuestionOptionRequest request3 = QuestionOptionRequest.builder().assessmentId(assessmentId).startingQuestion(76).build();
        CompletableFuture<List<QuestionResponseData>> questions3 = questionService.getQuestions(request3);

        CompletableFuture.allOf(questions, questions1, questions2, questions3).join();

        //return questionService.getQuestions(questionOptionRequest);
    }
    
 

Комментарии:

1. CompletableFuture::allOf возвращает a CompletableFuture<Void> . Вам придется создать список результатов вручную.

2. У вас есть 4 отдельных списка результатов, поэтому, по-видимому, вам нужно объединить их в один список. Подумайте о добавлении этапа «Принятие» к каждому отдельному будущему, который перемещает его результат в объединенный список, а затем дождитесь завершения всех этих этапов.

Ответ №1:

  CompletableFuture<List<QuestionResponseData>> futures = new CompletableFuture[]{request, request1, request2, request3};

 List<QuestionResponseData> result =
    CompletableFuture.allOf(futures)
            .thenApply(_void -> Arrays.stream(futures).map(CompletableFuture::join).flatMap(List::stream).collect(Collectors.toList()))
            .join();
 

Обратите внимание, что вызов CompletableFuture::join на самом деле не блокируется, блокировка уже произошла в CompletableFuture::allOf