Через месяц у меня возникли проблемы только с Javascript/Typescript.
Например, давайте посмотрим этот фрагмент:
@Test
public void testAsync(){
CompletableFuture.supplyAsync(()->{
try{
Thread.sleep(10000);
System.out.println("After some seconds");
}catch(InterruptedException exc){
return "Fail";
}
return "Done";
}).thenAccept(s->System.out.println(s)).join();
System.out.println("should write before After some seconds statement");
}
Я ожидал, что последний system.out.println будет запущен до CompletableFuture, но он ожидает завершения Future.
Итак, что я получил: «Через несколько секунд» "Готово" «следует написать перед заявлением «После нескольких секунд»»
Что я хочу: «следует написать перед заявлением «После нескольких секунд»» «Через несколько секунд» "Готово"
Как я могу этого добиться?
Сохраните будущее в переменной, распечатайте оператор, затем join()
дождитесь результата:
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(10000);
System.out.println("After some seconds");
} catch (InterruptedException exc) {
return "Fail";
}
return "Done";
}).thenAccept(s -> System.out.println(s));
System.out.println("should write before After some seconds statement");
future.join();
Что касается объяснения, в javadoc метода .join()
говорится:
Returns the result value when complete, or throws an (unchecked) exception if completed exceptionally
То есть, если вы вызываете .join()
, связанную с thenAccept()
, это означает, что вы сначала дождетесь окончания supplyAsync()
, затем thenAccept()
и будете ждать такого результата через join()
.
Следовательно, вы достигнете своего System.out.println("should write before After some seconds statement");
сразу после завершения всех операций.
Если вашей целью было дождаться будущего перед завершением теста, то вам следует вызывать join()
после печати в основном потоке, а не до него.
Удалить
join()
? Или переместить его после печати?