【輪詢】【ajax】【js】【spring boot】ajax超時請求:前端輪詢處理超時請求解決方案 + spring boot服務設置接口超時時間的設置


 

 

場景描述:

ajax設置timeout在本機測試有效,但是在生產環境等外網環境無效的問題

 

1.ajax的timeout屬性設置 前端請求超時事件【網絡連接不穩定時候,就無效了】

var data = JSON字符串; $.ajax({ type: "POST", url: url, dataType: 'json', timeout: 3000,//3s鍾超時
 data: data, xhrFields: { withCredentials: true }, success: function (json) { alert("保存成功") }, error: function (err, textStatus, errorThrown) { alert("保存失敗") } });

 

屬性說明:

timeout: //單位是毫秒值 timeout: 0  //代表永不超時 

 

其他說明:

當然,ajax里面設置的是前端超時事件,后端服務 的接口 也有超時時間。 
聲明: timeout屬性設置的超時時間,肯定是有效果的。
但是  在生產環境等時候,因為網絡跳動不穩定,導致 前后端連接中斷了,即使這里的超時時間設置再大  或者設置永不超時,也會進入error,即會發生超時情況。這種時候,就需要 在前端使用輪詢去解決這種問題了。

 

 

 

2.spring boot為例,設置接口超時時間的兩種方式

 

1> 在配置文件application.properties中加了spring.mvc.async.request-timeout=20000,意思是設置超時時間為20000ms即20s,
2>還有一種就是在config配置類中加入 public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void configureAsyncSupport(final AsyncSupportConfigurer configurer) { configurer.setDefaultTimeout(20000); configurer.registerCallableInterceptors(timeoutInterceptor()); } @Bean public TimeoutCallableProcessingInterceptor timeoutInterceptor() { return new TimeoutCallableProcessingInterceptor(); } }

 

 

 

 

3.前端輪詢方案 ,查詢后端的保存狀態,直到查詢到后端的保存狀態為成功,才做相應的用戶響應操作 【解決ajax設置timeout避免不了的網絡不穩定的問題】

輪詢方案簡介:

這里就要對 1中的 ajax進行改造了 。
這里使用 js的  setInterval()發起輪詢     clearInterval()停止輪詢


setInterval(code,millisec) 參數 描述 code 必需。要調用的函數或要執行的代碼串。 millisec 必須。周期性執行或調用 code 之間的時間間隔,以毫秒計。 setInterval() 方法可按照指定的周期(以毫秒計)來調用函數或計算表達式。 setInterval() 方法會不停地調用函數,直到 clearInterval() 被調用或窗口被關閉。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的參數。

 

輪詢方案代碼:

var data = JSON字符串; var myFlag = new Date().getTime();     //作為本次保存的 唯一標識
                data.myFlag = myFlag;  //作為后端入參傳給后台
 $.ajax({ type: "POST", url: url, dataType: 'json', timeout: 0,//永不超時
 data: data, xhrFields: { withCredentials: true }, success: function (json) { alert("處理成功的邏輯 依舊寫在這里"); }, error: function (err, textStatus, errorThrown) { //此處要判斷 error時候,是不是因為超時導致的,如果是超時導致的error,那就做輪詢
                        if (textStatus == 408 || textStatus == 'timeout') { //輪詢查詢批量保存狀態
                            window.myFlag2222 = setInterval(function (){ this.batchSaveTimer(myFlag); },6000); }else { loading.hide(); $('.J_button_submit').prop('disabled', false); tips.show("保存失敗"); } } }); batchSaveTimer: function (flag) { $.ajax({ type:'get', url: url + "/" + flag, dataType:'json', cache:true, xhrFields: { withCredentials: true }, success:function(result) { if (result.code && result.code == 'success' ) { //當后端保存狀態為1 代表保存成功
                if (result.data == '1') { //這里就 停止輪詢 入參一定是 發起輪詢的setInterval()方法的返回值
 clearInterval(window.myFlag2222); alert("這里同樣寫一份  處理成功的邏輯"); //當后端保存狀態為-1 代表保存失敗
                } else if (result.data == '-1') { //這里視業務而定,是否停止輪詢
 clearInterval(window.myFlag2222); alert("這里寫一份  處理失敗的邏輯"); } } }, error:function() { alert("服務器異常") } }); },

 

附錄說明:

當然,后端處理也很簡單,在redis記錄一個 status. myFlag作為key status作為value 開始保存,把status設置為0 開始處理 status設置為1 處理成功 status設置為-1 處理失敗

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM