2016-07-23 59 views
2

我通過AJAX調用在後臺生成PDF。生成PDF需要一些時間(大約一秒左右)。只有在完成前一個AJAX調用時才執行下一個AJAX調用

下面的工作正常,但問題是我用完內存。 因此,我只想在以前的AJAX調用完成時纔開始計算(即只發出AJAX調用)。

我玩過async: false,但它凍結了我的頁面,這是不受歡迎的行爲(無論如何都會使用async)。

我的代碼:

$("div[data-myid]").each(function(){ 

    var myid= $(this).data('myid'); 
    var my_div = $(this); 

    $.ajax({ 
     url: "/my_ajax/" + myid + "/", 
    }).done(function (data) { 
     my_div.html(data.message + ' <a href="' + data.url + '">Download</a>'); 
    }); 

}); 

HTML:

<table> 
    <tr> 
     <td><div id="div_260" data-myid="260">Queued..</div></td> 
    </tr> 
    <tr> 
     <td><div id="div_259" data-myid="259">Queued..</div></td> 
    </tr> 
</table> 

注意該表是動態生成的,一般包含超過100行。

關於如何最好地接近這個的任何想法?

+0

您可以利用使用webWorkers的工作? –

+0

@ RokoC.Buljan:我從來沒有使用WebWorkers,但這些似乎正在執行一個外部的JS文件 - 不知道這可能會有幫助嗎?你能提供一些背景嗎? – SaeX

回答

5

接下來ajax只應在當前ajax調用完成後觸發。下面的代碼將幫助你實現它。

實現它的步驟。

  • 創建一個數組,並將數組中的DOM對象推送到所有div。
  • 爲ajax調用創建一個函數,遞歸調用它爲所有 div。
  • doAjax函數將在ajax成功函數中調用。因此, 下一個Ajax將只在當前完成後被觸發。

這是我的代碼:

<script type="text/javascript">  

    var elementArray = []; 

    //Code to push all divs in elementArray 
    $(document).ready(function(){ 
     $("div[data-myid]").each(function() { 
      elementArray.push($(this)); 
     }); 
     // First ajax call. 
     doAjax(0); 
    }); 

    //Function to ajax fire 
    function doAjax(arrCount) 
    { 
     var myid = elementArray[arrCount].data("myid"); 
     var my_div = elementArray[arrCount]; 

     $.ajax({ 
      url: "/my_ajax/" + myid + "/", 
      type:"POST", 
      dataType:"json", 
      success: function (data) {    
       if (arrCount < elementArray.length-1) { 
       { 
        my_div.html(data.message + ' <a href="' + data.url + '">Download</a>'); 
        arrCount++; 
        //Next ajax call when current ajax call has been finished. 
        doAjax(arrCount); 
       }   
      } 
     }); 
    } 

</script> 
+0

智能解決方案太:) –

+0

@MarkoMackic:謝謝:) –

1

也許是這樣的:

function postponeAjax(index,element){ 
    var myid= $(element).data('myid'); 
    var my_div = $(element); 
    setTimeout(function(){ 
     $.ajax({ 
      url: "/my_ajax/" + myid + "/", 
     }).done(function (data) { 
      my_div.html(data.message + ' <a href="' + data.url + '">Download</a>'); 
     }); 
     },index*2000); 

    } 
    $("div[data-myid]").each(function(index,element){ // if I remember well 
     postponeAjax(index,element) 
    }); 

這是一種哈克解決方案,但我認爲它應該工作:) 下面是使用for循環https://repl.it/CfJA基本例如replit。 2000年的延遲,對其進行修改,以適應PDF的創建時間+ 1秒一些寬容:)

編輯:

有這個當完成最後一個Ajax調用時調用方便的函數

$(document).ajaxStop(function() { 
    // place code to be executed on completion of last outstanding ajax call here 
}); 

因此,我們可以做這樣的事情:

var number_of_elements = $("div[data-myid]").length; 
    var current_index = 0; 
    var myid, mydiv; 

    function doAjax(){ 
     mydiv = $("div[data-myid]:eq("+current_index+")")) 
     myid = mydiv.data('myid'); 
     $.ajax({ 
      url: "/my_ajax/" + myid + "/", 
     }).done(function (data) { 
      my_div.html(data.message + ' <a href="' + data.url + '">Download</a>'); 
     }); 
     current_index++; 
    } 
    //repeat until there is no more elements 
    $(document).ajaxStop(function(){ 
     if(current_index < number_of_elements){ 
     doAjax(); 
     } 
    }); 
    //init the sequence 
    doAjax(); 

我沒有測試過這一點,所以通知我,如果它不工作:d

+0

這的確看起來很骯髒。問題是我的pdf生成也不是靜態的(可能需要0.5或3秒,這取決於它包含的數據)。默認延遲3秒也不是理想的。 – SaeX

+0

我得到這個:P :)只是第二個 –