最近在做項目時,有一個需求是批量打印好多個合同,使用AJAX向后台傳送數據,等待后台執行后,需要把生成之后的文件地址傳送過來。
后台的處理時間比較長,根據合同的多少可能等待時間比較長,會達到10s左右,這個時候如果不加任何的提示,會導致用戶因為沒有看到是否執行而導致重復的操作,為了增加用戶的體驗感,,以及項目的完善性,這個時候就需要增加一個等待頁面進行提示。
我們先來看一個Ajax同步請求與異步請求的區別:
異步和同步:
ajax中 async屬性是設置同步和異步,async:false,時表示此時ajax為同步請求,如果不寫或者設置成true表示異步請求
$.ajax({ type : "get", async:true, url : success : function(targetPath){ }, })
當設置成同步時,意味着執行完當前的程序段,才能執行下一段,它屬於阻塞模式,其表現在網頁上面就是會出現頁面假死現象,也就是暫停當前的頁面,用戶不能操作其它的,必須等待當前請求返回數據,在這個過程中用戶看不到任何的提示以及等待提醒。
而使用異步方式請求,頁面后再次段程序等待的時候,繼續的向下執行,等待執行結束再返回結果,頁面不會出現假死現象。
我現在遇到的問題是:點擊一個按鈕,使用Ajax向后台傳送數據,等待后台的執行,由於后台執行時間過長,這個時候頁面出現所謂的假死現象,容易引發誤操作。
我的思路是:在ajax返回結果之前,增加一個遮罩層的函數顯示效果,在執行之后,顯示隱藏效果,於是我寫了一個遮罩層的函數,准備放到ajax中。
我通過查閱各種帖子發現有類似的描述,說是可以使用ajax的一個屬性進行設置
beforeSend: function(){)
,類似:
$.ajax(function(){ //省略了一些參數,這里只給出async 和 beforeSend async: false, //同步請求,默認情況下是異步(true) beforeSend: function(){ $(‘#warning‘).text(‘正在處理,請稍等!‘); } });
新片場https://www.wode007.com/sites/73286.html 傲視網https://www.wode007.com/sites/73285.html
但是設置成這樣效果是出不來的,因為beforeSend只有在ajax設置成異步請求時,才會顯示出beforeSend中函數的效果。
在這里根據業務需要,ajax是不能改為異步的,因為必須等待文件地址返回后才能繼續后面的操作。
除此之外,loading也使用過,還有各種加提示的方法,但是sys為異步時,效果都會無法顯示。
在這個時候就需要引入一個JQuery中一個對象deferred,來對ajax進行封裝異步函數。
主要使用的是deferred中 $.when的方法使用,主要是對多個deferred對象進行並行化操作,當所有deferred對象都得到解決就執行后面添加的相應回調
具體使用如下:
使用之前需要先進行聲明
var defer = $.Deferred(); function toGetData() { var defer = $.Deferred(); var checkedIds=$("input[name=‘backEntrust‘]:checked"); if(checkedIds.length==0){ alert("請選中要打印的合同"); return false; } var r=confirm("確定打印嗎?"); if (r==true){ var enIds=new Array(checkedIds.length); for(var i=0; i<checkedIds.length; i++){ enIds[i] = checkedIds[i].value; } $.ajax({ type : "get", async:true, url :"${pageContext.request.contextPath}/renWuFenPeiService_mergerSample.action?entrustIds="+enIds, success : function(targetPath){ defer.resolve(targetPath) }, error : function() { alert("樣品檢測委托單合並失敗,請重試。"); } }); }else { window.location.reload(); } return defer.promise(); } $(‘#batchPrint‘).on(‘click‘, function() { loading(); 顯示遮罩層函數 $.when(toGetData()).done(function(targetPath){ $(".shodow").hide() $("#batchPrinttwo").attr("href","/file/"+targetPath); document.getElementById("batchPrinttwo").click(); loaded(); 取消遮罩層函數 }); });
在這段代碼中,我們可以看到ajax設置的是異步請求,但是我們需要的是同步請求啊,在這使用了JQuery中的deferred之后,我們想要的顯示效果就出來了,我們就可以使用ajax的異同請求,達到同步的效果。