vue接口总是请求超时_调用接口处理时间过长,前端访问超时解决方案

项目中因后台执行计算耗时,前台请求易超时,如自动排课。解决方案是改造为轮询查询程序执行结果,后台将排课接口分为创建线程执行和查询结果两部分,结果存于Redis;前端分两次请求,先启动排课,再轮询查询结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在项目中会遇到这样的情况,由于后台需要执行、计算一段时间(如计算积分、自动排课等)。这时前台请求一段时间后,得不到返回结果就会发生请求超时。

拿自动排课来说,如果一个学校上百个班级,执行一次排课可能需要1-2分钟甚至更长时间,那么会造成前台访问接口超时(当然也可以延长超时时间实现)。

解决方案:

考虑改造为轮询查询程序执行结果。

1. 后台改造:

将自动排课功能的接口分为两个:

①创建线程执行自动排课

②提供接口查询排课结果

对原有的方法进行改造:原有的方法,方法执行完成后才会返回执行结果。时间过长,考虑将原方法改造为线程执行,这样一旦线程开始执行,就可以返回结果。

改造方法:

自动排课功能所在的service类实现Runnable接口,将自动排课的实现逻辑写在run方法中。

编写方法①创建并执行线程,执行run方法。

Controller层调用方法①实现自动排课功能。

对于自动排课结果,可以放在redis中,接口①实时更新自动排课的状态(成功或者失败),可以通过接口②每间隔一段时间查询自动排课的结果。

代码示例:

Controller层

@Controller

public class Controller{

@Autowired

//自动注入排课功能所在的service

private CourseTableService courseTableService;

@RequestMapping(value = "/arrange/{id}")

@ResponseBody

public ResponseMessage arrange(@PathVariable String id) {

return courseTableService.arrange(id); //自动排课

}

@RequestMapping(value = "/arrangeResult/{id}")

@ResponseBody

public Map arrangeResult(@PathVariable String id) {

//查询自动排课结果,并返回

}

}

Service层

@Service

@Transactional(readOnly = true)

public class CourseTableService implements Runnable { //实现Runnable接口

@Autowired

private ThreadPoolTaskExecutor taskExecutor; //线程池

//自动paike

public ResponseMessage arrange(String scheduleId) {

this.scheduleId=scheduleId; //设置run方法中需要用的参数

taskExecutor.execute(this); //执行线程

return ResponseMessage.ok(); //返回线程执行结果

}

//自动排课,线程

public void run(){

//排课逻辑代码

String scheId=this.scheduleId; //使用接收的参数

}

}

2. 前端大致分两次请求后台接口:

第一次请求接口自动排课(线程或者mQ执行),这样在启动自动排课的时候就返回请求结果,告知用户正在进行排课。

然后轮询调用第二接口,每隔几秒钟就去查询排课的结果。如果返回的状态为0代表排课成功,提示用户;如果返回的状态为1达标排课失败,提示失败原因;如果返回的状态为2代表排课正在执行中,继续轮询访问查询排课结果的接口。

主要代码示例:

var intervalFlag=true; //是否执行轮询的标志

//_post2是封装的ajax请求,

$._post2('/arrange/' + _id, {}, function(res) {

var interVal;

//调用接口,查询自动排课结果,加上这个是为了用户点击后立马访问,ajax同步访问,

//因为这次的查询结果决定了,是否执行轮询。

getProgress(_id, interVal);

if(intervalFlag){

//第一次查询结果表明排课还在进行中,才会执行轮询。

//如果第一次已经返回结果表示程序执行完成,就不需要轮询访问排课结果了。

interval(_id);

}

});

// 进度查询

function getProgress(_id, interVal) {

$._post2('/arrangeResult/' + _id, {}, function(res) {

if (res.arrangeStatus == 0) {

//排课成功

clearInterval(interVal); //清空轮询

intervalFlag=false; //设置为不执行轮询

}else if(res.arrangeStatus==1){

//排课失败

clearInterval(interVal);

intervalFlag=false;

}else if(res.arrangeStatus==2){

//排课进行中,什么都不做

}

});

}

// 隔两秒访问

function interval(_id) {

var pro;

// 定时器

var interVal;

interVal = setInterval(function() {

// 获取返回对象

pro = getProgress(_id, interVal);

}, 2000);

}

前端使用 Vue 进行接口请求时,我们可以使用一些方法来设置请求超时时间并终止当前请求。 首先,在Vue中使用axios库进行接口请求。axios是一个非常强大的HTTP库,它可以用于向后端发送请求,并且具有很多配置选项,包括设置请求超时时间。 我们可以通过在axios请求中设置timeout选项来设置超时时间,单位为毫秒。例如,我们可以将超时时间设置为5000毫秒(5秒): ```javascript axios.get('/api/someData', { timeout: 5000 }) .then(response => { // 处理返回的数据 }) .catch(error => { if (axios.isCancel(error)) { console.log('请求超时'); // 在这里可以进行相关处理,例如给用户提示等操作 } // 处理其他错误 }); ``` 在上面的代码中,我们设置了超时时间为5秒。如果请求在5秒内没有得到响应,就会抛出一个错误。 另外,我们还可以使用 axios.CancelToken 的方式来取消请求。例如,我们可以创建一个 CancelToken 实例,然后将其作为 cancelToken 选项传递给 axios 请求: ```javascript const CancelToken = axios.CancelToken; let cancel; axios.get('/api/someData', { cancelToken: new CancelToken(function executor(c) { // executor 函数接收一个 cancel 函数作为参数 cancel = c; }) }) .then(response => { // 处理返回的数据 }) .catch(error => { if (axios.isCancel(error)) { console.log('请求被取消'); // 在这里可以进行相关处理,例如给用户提示等操作 } // 处理其他错误 }); // 通过调用 cancel 函数可以取消请求 cancel(); ``` 在上面的代码中,我们创建了一个 CancelToken 实例,并将其作为 cancelToken 选项传递给请求。同时,我们可以通过调用 cancel 函数来取消请求。 综上所述,我们可以利用axios的timeout选项来设置请求超时时间,并且可以使用cancelToken来取消请求,以达到终止当前请求的目的。这样可以提高用户体验,防止长时间等待。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值