调用一个使用CompletableFuture的thenAccept()的方法。

问题描述 投票:0回答:1

我有一个休息API函数,它返回一个类型为DeferredResult的对象,我正在写一个函数,它将调用apiMethod()并使用它的响应。

import org.springframework.web.context.request.async.DeferredResult;

public DeferredResult<Object> apiMethod{
CompletableFuture<Object> future = someMethod();
final DeferredResult<Object> response = new DeferredResult<>(); 

future.thenAccept(){
    //logic to populate response
}

return response;
}

我正在写一个函数,它将调用apiMethod()并使用它的响应。我最终总是得到一个空的响应,因为响应是在future.thenAccept()中填充的。有什么方法可以处理这个问题吗?

java spring-boot completable-future
1个回答
1
投票

问题是该方法继续执行,而 thenAccept 运行异步。在你调用 thenAccept,该方法只返回 response 之后,与它是否已经被填充无关。

想象一下下面的简单代码。

    public static void main(String[] args) {
        AtomicReference<String> result = new AtomicReference<>(null);
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            for (int i = 0; i < 100_000_000; i++) {}
            return "Hello World!";
        });
        future.thenAccept(s -> {
            result.compareAndSet(null, s);
        });
        System.out.println(result.get());
    }

你可能期望 "Hello World!" 打印,但事实并非如此;它打印出的是 null. 这里也有同样的问题:主线程打印值,而这个值会在某个时候被异步更新。你可以通过加入未来来解决这个问题。

    public static void main(String[] args) {
        AtomicReference<String> result = new AtomicReference<>(null);
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            for (int i = 0; i < 100_000_000; i++) {}
            return "Hello World!";
        });
        CompletableFuture<Void> end = future.thenAccept(s -> {
            result.compareAndSet(null, s);
        });
        end.join();
        System.out.println(result.get());
    }

现在当我们加入异步未来链,或者说是加入一个设置值的未来链时, 我们将看到主线程打印出的是 "Hello World!" 因为它将等待未来完成。

现在你只需要在你的代码中应用这个修正。

© www.soinside.com 2019 - 2024. All rights reserved.