2016-07-23 58 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 :)只是第二个 –