### Question:
DefaultCompletableAsyncResult implements CompletableAsyncResult<T> { @Override public <U> AsyncCompletion thenAcceptBoth(AsyncResult<? extends U> other, BiConsumer<? super T, ? super U> consumer) { requireNonNull(other); requireNonNull(consumer); return new DefaultCompletableAsyncCompletion(future.thenAccept(t -> other.thenAccept(u -> consumer.accept(t, u)))); } DefaultCompletableAsyncResult();   DefaultCompletableAsyncResult(CompletableFuture<T> future); @Override boolean complete(@Nullable T value); @Override boolean completeExceptionally(Throwable ex); @Override boolean cancel(); @Override boolean isDone(); @Override boolean isCompletedExceptionally(); @Override boolean isCancelled(); @Override @Nullable T get(); @Override @Nullable T get(long timeout, TimeUnit unit); @Override AsyncResult<U> then(Function<? super T, ? extends AsyncResult<U>> fn); @Override AsyncResult<U> thenSchedule(Vertx vertx, Function<? super T, ? extends AsyncResult<U>> fn); @Override AsyncCompletion thenCompose(Function<? super T, ? extends AsyncCompletion> fn); @Override AsyncCompletion thenRun(Runnable action); @Override AsyncCompletion thenScheduleRun(Vertx vertx, Runnable runnable); @Override AsyncCompletion thenScheduleBlockingRun(Vertx vertx, Runnable runnable); @Override AsyncCompletion thenScheduleBlockingRun(WorkerExecutor executor, Runnable runnable); @Override AsyncResult<U> thenApply(Function<? super T, ? extends U> fn); @Override AsyncResult<U> thenScheduleApply(Vertx vertx, Function<? super T, ? extends U> fn); @Override AsyncResult<U> thenScheduleBlockingApply(Vertx vertx, Function<? super T, ? extends U> fn); @Override AsyncResult<U> thenScheduleBlockingApply(WorkerExecutor executor, Function<? super T, ? extends U> fn); @Override AsyncCompletion thenAccept(Consumer<? super T> consumer); @Override AsyncCompletion thenAcceptBoth(AsyncResult<? extends U> other, BiConsumer<? super T, ? super U> consumer); @Override AsyncResult<V> thenCombine(
      AsyncResult<? extends U> other,
      BiFunction<? super T, ? super U, ? extends V> fn); @Override AsyncResult<T> exceptionally(Function<Throwable, ? extends T> fn); @Override AsyncResult<T> whenComplete(BiConsumer<? super T, ? super Throwable> action); @Override AsyncResult<U> handle(BiFunction<? super T, Throwable, ? extends U> fn); @Override AsyncCompletion accept(BiConsumer<? super T, Throwable> consumer);  }### Answer:
@Test void thenAcceptBoth() throws Exception { CompletableAsyncResult<String> asyncResult = AsyncResult.incomplete(); CompletableAsyncResult<String> asyncResult2 = AsyncResult.incomplete(); AtomicReference<String> ref = new AtomicReference<>(); AsyncCompletion completion = asyncResult.thenAcceptBoth(asyncResult2, (value, value2) -> { ref.set(value + value2); }); asyncResult.complete("Completed1"); asyncResult2.complete("Completed2"); assertThat(completion.isDone()).isTrue(); assertThat(ref.get()).isEqualTo("Completed1Completed2"); }