前端异步获取易超时请求结果
使用场景
前端页面发起一个查询请求,但是呢,由于数据量太大或网络等等问题,超时啦!
而这个前端页面是用php写哒,使用了php-fpm来进行进程管理,代理服务器使用的是nginx
那么当进程超时,前端就会返回504 超时错误啦~
当返回504后,该用户会有一段时间访问不了网站,体验感相当不佳呀!!!
解决方案
- 把这些容易超时的请求修改为异步请求
- 请求后返回给前端一个请求查询ID
- 后端处理该查询请求,当查询结束后保存结果
- 前端通过后端返回的查询id进行轮询,当查询到结果后进行页面渲染
方案技术要点
后端异步执行请求
前端ajax请求,页面渲染,根据字段适配生成表格
后端实现
使用语言 golang
首先呢,我们定义一个监听程序 func RequestExecListener() 该程序在获取到需要执行的请求时,执行 requestExec(item),否则每隔一秒输出 “free”
//监听程序
func RequestExecListener() {
for {
select {
case item := <- ListenerChan :
go requestExec(item)
case <- time.After(1*time.Second) :
fmt.Println("free... ")
}
}
}
定义了一个chan类型变量,存储请求
var ListenerChan = make(chan ListenerItem, 100)
定义一个请求结构,包括请求id,请求方法
type ListenerItem struct {
ID string
RequestFunc func() interface{}
}
当请求发送时,通过send函数,将请求结构数据发送至chan中,等待执行
func requestSend(id string,request func()interface{}) {
ListenerChan <- ListenerItem{
ID:id,
RequestFunc:request,
}
}
具体执行函数
func requestExec(item ListenerItem) {
ret := item.RequestFunc()
//将函数执行结果进行保存
saveRet(item.ID,ret)
}
func saveRet(id string,ret interface{}) {
//添加保存结果代码
}
func getRet(id string) interface{} {
//通过id将保存的结果返回
return nil
}
最后在main 主程序中执行这个监听程序就可以啦~
func main() {
go RequestExecListener()
for {
select {
}
}
}
前端实现
主要就是通过一个setInterval方法来轮训请求接口~
function get_request_ret(id, tableItem, dataArray) {
//等待时间
var waitingtime = 0;
//设置定时,隔1s获取返回结果,若获取到则clearInterval
var interval = setInterval(function () {
$.ajax(url, {"id": id}, function (e) {
if (e.error > 0) {
waitingtime++;
} else {
clearInterval(interval);
//将返回数据 转换为 json
var dataJsonRet = JSON.parse(e.data);
//生成渲染html
var appendHtml = "";
//遍历返回的数据
for (var item in dataJsonRet) {
appendHtml += "<tr>";
//根据自己自定义的dataArray进行赋值
appendHtml += "</tr>";
}
//将生成的html 插入至你指定的选择器中
tableItem.append(appendText);
}
});
});
}