专业编程基础技术教程

网站首页 > 基础教程 正文

用CompletableFuture当做SpringBoot的返回值会发生什么情况?

ccvgpt 2024-10-12 13:59:08 基础教程 7 ℃

在Spring Boot中,如果将CompletableFuture作为控制器方法的返回值,它会被自动处理为一个异步的请求,也就是说在Spring MVC中会自动检测返回值为CompletableFuture的请求处理,然后在这个CompletableFuture返回成功的时候异步的发送响应请求。

具体情况

也就是说当返回了一个CompletableFuture的时候,Spring Boot应用程序是不会阻塞线程的执行的而是直接进行了返回,然后在CompletableFuture完成之后将结果发送给客户端,这种需要进行异步处理场景有很多例如文件处理、远程服务调用等

用CompletableFuture当做SpringBoot的返回值会发生什么情况?

当CompletableFuture处理完成的时候,Spring会将结果转换为HTTP响应并返回给客户端,这个时候如果在CompletableFuture包含的是一个异常信息的话,Spring也会将异常转换为适当的HTTP错误响应。

在Spring Boot中内置了很多异步的处理返回支持,所以不需要开发者去做额外的配置处理,只需要将返回类型声明为CompletableFuture<T>即可,Spring会自动对其进行处理。

示例代码

@RestController
public class AsyncController {

    @GetMapping("/async")
    public CompletableFuture<String> asyncMethod() {
        return CompletableFuture.supplyAsync(() -> {
            // 模拟长时间操作
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello, World!";
        });
    }
}

在上面的例子中,客户端发送请求到/async路径时,SpringBoot会立即返回一个CompletableFuture,但并不会阻塞。在后台,CompletableFuture.supplyAsync会异步执行,完成后返回"Hello, World!",并且Spring会将该值返回给客户端。

这里需要注意,CompletableFuture.supplyAsync默认使用ForkJoinPool.commonPool(),因此我们可以自定义线程池来管理异步任务的执行。由于是异步操作,如果请求执行时间较长,可能需要处理超时逻辑。

前端如何处理上面的这个返回

在前端处理Spring Boot返回的CompletableFuture异步结果时,假设前端是使用JavaScript(例如,通过Fetch API或Axios),可以通过如下的方式来对CompletableFuture进行处理。

使用fetch示例

// 发送异步请求到 /async
fetch('/async')
    .then(response => {
        if (!response.ok) {
            // 处理HTTP错误
            throw new Error('Network response was not ok');
        }
        return response.text(); // 假设返回的是文本内容
    })
    .then(data => {
        console.log('Received:', data); // 处理响应数据
    })
    .catch(error => {
        console.error('There was a problem with the fetch operation:', error);
    });

使用axios示例

// 使用 axios 发送请求到 /async
axios.get('/async')
    .then(response => {
        console.log('Received:', response.data); // 处理响应数据
    })
    .catch(error => {
        console.error('There was an error!', error);
    });

无论使用fetch还是axios,前端都在等待一个Promise的完成。在上面的Spring Boot例子中,当CompletableFuture完成后,Spring会自动将结果发送到前端。前端接收到响应后可以处理数据,例如更新UI或执行其他逻辑。

展示加载状态

由于后端的操作是异步的,前端通常会在等待期间显示一个加载指示器来提升用户体验,如下所示。

const loadData = async () => {
    try {
        // 显示加载状态
        document.getElementById('loader').style.display = 'block';

        // 发送异步请求
        const response = await fetch('/async');
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }

        // 处理响应
        const data = await response.text();
        console.log('Received:', data);

        // 更新UI
        document.getElementById('result').textContent = data;

    } catch (error) {
        console.error('Fetch error:', error);
    } finally {
        // 隐藏加载状态
        document.getElementById('loader').style.display = 'none';
    }
};

// 调用函数
loadData();

总结

在前端处理Spring Boot返回的异步CompletableFuture响应时,我们只需像处理普通的HTTP请求一样,使用fetch或axios发送请求并等待结果。前端会根据后端的返回值更新UI或进行进一步处理。如果操作时间较长,可以显示一个加载动画来提升用户体验。

Tags:

最近发表
标签列表