关于后端异步+前端进度条的简单实现

优化API接口:使用SpringBoot实现异步任务与前端进度跟踪
文章描述了一个通过SpringBoot框架改进API接口的过程,使用异步任务处理大量用户授权,同时在前端展示实时进度条,以提高性能并改善用户体验。

举个例子,现在有一个接口,就拿若依的批量给用户授权角色接口来说。
原来的接口是这样的

    /**
     * 批量选择用户授权
     */
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.GRANT)
    @PutMapping("/authUser/selectAll")
    public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds)
    {
   
   
        List<Long> userIdList = Arrays.stream(userIds).collect(Collectors.toList());
		sysRoleService.insertAuthUsers(roleId, Arrays.asList(userIdList));
        return AjaxResult.success(taskId);
    }

直接在前端获取到用户id然后就直接在sysRoleService.insertAuthUsers方法中进行数据库操作了。
如果前端用户数据量太大的话,这样返回会很慢,导致前端加载时间长,现在简单的改造这个方法。

首先写一个线程池,执行异步的时候调用。

@Configuration
@EnableAsync
public class AsyncThreadPoolConfig implements AsyncConfigurer {
   
   

    private static ThreadPoolTaskExecutor executor;
    //获取单前机器cpu数量
    private static final int cpu = Runtime.getRuntime().availableProcessors();
    //设置核心线程数
    private static final int corePoolSize = cpu;
    //设置最大线程数
    private static final int maxPoolSize = 1000;
    //设置线程空闲时间()
    private static final int keepAliveTime = 60;
    //设置主线程等待时间
    private static final int awaitTerminationSeconds = 120;
    //缓存队列数
    private static final int queueCapacity = 200;
    //线程池前缀名
    private static final String threadNamePrefix = "ryTaskExecutor-";

    public static ThreadPoolTaskExecutor getExecutor() {
   
   
        return executor;
    }

    @Bean("ryTaskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
   
   
        executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        //等待队列大小
        executor.setQueueCapacity(queueCapacity);
        //空闲时间
        executor.setKeepAliveSeconds(keepAliveTime);
        executor.setThreadNamePrefix(threadNamePrefix);
        executor.setAwaitTerminationSeconds(awaitTerminationSeconds);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // RejectedExecutionHandler:当pool已经达到max-size的时候,如何处理新任务
        // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

异步任务进度条

public class AsyncTaskProgress implements Serializable {
   
   
    private static final long serialVersionUID = 1L;

    private String status; // 任务状态:PENDING-进行中,SUCCESS-成功,FAILURE-失败
    private Integer progress; // 任务进度:0-100
    private String result; // 任务结果(仅在状态为SUCCESS时有用)
    private String error; // 任务失败原因(仅在状态为FAILURE时有用)

    public String getStatus() {
   
   
        return status;
    }

    public void setStatus(String status) {
   
   
        this.status = status;
    }

    public Integer getProgress() {
   
   
        return progress;
    }

    public void setProgress(Integer progress) {
   
   
        this.progress = progress;
    }

    public String getResult() {
   
   
        return result;
    }

    public void setResult(String result) {
   
   
        this.result = result;
    }

    public String getError() {
   
   
        return error;
    }

    public void setError(String error) {
   
   
        this.error = error;
    }
}

新建异步任务实现类

@Service
public class AsyncTaskService {
   
   

    private static final String REDIS_PREFIX = "ASYNC_TASK_"; // Redis中保存异步任务进度对象的前缀
    @Autowired
    public RedisTemplate redisTemplate;
	
	//生成异步任务的id,用于前端查询改任务的进度使用
    public String generateTaskId() {
   
   
        return UUID.randomUUID().toString();
    <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值