1. 程式人生 > >使用Ajax同步請求時,等待時間過長增加頁面提示問題

使用Ajax同步請求時,等待時間過長增加頁面提示問題

最近在做專案時,有一個需求是批量列印好多個合同,使用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('正在處理,請稍等!'); } });

但是設定成這樣效果是出不來的,因為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的異同請求,達到同步的效果。