public static < T > CompletableFuture < Void > doWhileLoop ( Supplier < CompletableFuture < T > > loopBody , Predicate < T > condition , Executor executor ) { CompletableFuture < Void > result = new CompletableFuture <> ( ) ; // We implement the do-while loop using a regular loop, but we execute one iteration before we create the actual Loop object. // Since this method has slightly different arguments than loop(), we need to make one adjustment: // * After each iteration, we get the result and run it through 'condition' and use that to decide whether to continue. AtomicBoolean canContinue = new AtomicBoolean ( ) ; Consumer < T > iterationResultHandler = ir -> canContinue . set ( condition . test ( ir ) ) ; loopBody . get ( ) . thenAccept ( iterationResultHandler ) . thenRunAsync ( ( ) -> { Loop < T > loop = new Loop <> ( canContinue :: get , loopBody , iterationResultHandler , result , executor ) ; executor . execute ( loop ) ; } , executor ) . exceptionally ( ex -> { // Handle exceptions from the first iteration. result . completeExceptionally ( ex ) ; return null ; } ) ; return result ; }
Executes a code fragment returning a CompletableFutures while a condition on the returned value is satisfied .