前端異步獲取易超時請求結果
使用場景
前端頁面發起一個查詢請求,但是呢,由於數據量太大或網絡等等問題,超時啦!
而這個前端頁面是用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);
}
});
});
}