最近在做項目時,有一個需求是批量打印好多個合同,使用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的異同請求,達到同步的效果。
