调用接口处理时间过长,前端访问超时解决方案
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
????在項(xiàng)目中會遇到這樣的情況,由于后臺需要執(zhí)行、計(jì)算一段時間(如計(jì)算積分、自動排課等)。這時前臺請求一段時間后,得不到返回結(jié)果就會發(fā)生請求超時。
????拿自動排課來說,如果一個學(xué)校上百個班級,執(zhí)行一次排課可能需要1-2分鐘甚至更長時間,那么會造成前臺訪問接口超時(當(dāng)然也可以延長超時時間實(shí)現(xiàn))。
解決方案:
????考慮改造為輪詢查詢程序執(zhí)行結(jié)果。
????1. 后臺改造:
????????將自動排課功能的接口分為兩個:
????????????①創(chuàng)建線程執(zhí)行自動排課
????????????②提供接口查詢排課結(jié)果
????????對原有的方法進(jìn)行改造:原有的方法,方法執(zhí)行完成后才會返回執(zhí)行結(jié)果。時間過長,考慮將原方法改造為線程執(zhí)行,這樣一旦線程開始執(zhí)行,就可以返回結(jié)果。
?
????????改造方法:
- 自動排課功能所在的service類實(shí)現(xiàn)Runnable接口,將自動排課的實(shí)現(xiàn)邏輯寫在run方法中。
- 編寫方法①創(chuàng)建并執(zhí)行線程,執(zhí)行run方法。
- Controller層調(diào)用方法①實(shí)現(xiàn)自動排課功能。
- 對于自動排課結(jié)果,可以放在redis中,接口①實(shí)時更新自動排課的狀態(tài)(成功或者失敗),可以通過接口②每間隔一段時間查詢自動排課的結(jié)果。
????????
????????代碼示例:
Controller層
@Controller public class Controller{@Autowired//自動注入排課功能所在的serviceprivate CourseTableService courseTableService; @RequestMapping(value = "/arrange/{id}")@ResponseBodypublic ResponseMessage arrange(@PathVariable String id) {return courseTableService.arrange(id); //自動排課}@RequestMapping(value = "/arrangeResult/{id}")@ResponseBodypublic Map<String,Object> arrangeResult(@PathVariable String id) {//查詢自動排課結(jié)果,并返回} }Service層
@Service @Transactional(readOnly = true) public class CourseTableService implements Runnable { //實(shí)現(xiàn)Runnable接口@Autowiredprivate ThreadPoolTaskExecutor taskExecutor; //線程池 //自動paikepublic ResponseMessage arrange(String scheduleId) {this.scheduleId=scheduleId; //設(shè)置run方法中需要用的參數(shù)taskExecutor.execute(this); //執(zhí)行線程return ResponseMessage.ok(); //返回線程執(zhí)行結(jié)果}//自動排課,線程public void run(){ //排課邏輯代碼String scheId=this.scheduleId; //使用接收的參數(shù)} }?
????2. 前端大致分兩次請求后臺接口:
????第一次請求接口自動排課(線程或者mQ執(zhí)行),這樣在啟動自動排課的時候就返回請求結(jié)果,告知用戶正在進(jìn)行排課。
????然后輪詢調(diào)用第二接口,每隔幾秒鐘就去查詢排課的結(jié)果。如果返回的狀態(tài)為0代表排課成功,提示用戶;如果返回的狀態(tài)為1達(dá)標(biāo)排課失敗,提示失敗原因;如果返回的狀態(tài)為2代表排課正在執(zhí)行中,繼續(xù)輪詢訪問查詢排課結(jié)果的接口。
????主要代碼示例:
var intervalFlag=true; //是否執(zhí)行輪詢的標(biāo)志 //_post2是封裝的ajax請求, $._post2('/arrange/' + _id, {}, function(res) { var interVal;//調(diào)用接口,查詢自動排課結(jié)果,加上這個是為了用戶點(diǎn)擊后立馬訪問,ajax同步訪問,//因?yàn)檫@次的查詢結(jié)果決定了,是否執(zhí)行輪詢。getProgress(_id, interVal); if(intervalFlag){//第一次查詢結(jié)果表明排課還在進(jìn)行中,才會執(zhí)行輪詢。//如果第一次已經(jīng)返回結(jié)果表示程序執(zhí)行完成,就不需要輪詢訪問排課結(jié)果了。interval(_id); } });// 進(jìn)度查詢 function getProgress(_id, interVal) {$._post2('/arrangeResult/' + _id, {}, function(res) {if (res.arrangeStatus == 0) {//排課成功clearInterval(interVal); //清空輪詢intervalFlag=false; //設(shè)置為不執(zhí)行輪詢}else if(res.arrangeStatus==1){//排課失敗clearInterval(interVal);intervalFlag=false;}else if(res.arrangeStatus==2){//排課進(jìn)行中,什么都不做}}); }// 隔兩秒訪問 function interval(_id) {var pro;// 定時器var interVal;interVal = setInterval(function() {// 獲取返回對象pro = getProgress(_id, interVal);}, 2000); }?
轉(zhuǎn)載于:https://my.oschina.net/u/3706132/blog/1550617
總結(jié)
以上是生活随笔為你收集整理的调用接口处理时间过长,前端访问超时解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大家好,给大家介绍一下,这是我的智能伙伴
- 下一篇: 通过js 判断当前应用是什么浏览器【借鉴