如果前一个AJAX调用完成,则仅执行下一个AJAX调用

时间:2016-07-23 13:40:28

标签: jquery ajax

我正在通过AJAX调用在后台生成PDF。生成PDF需要一些时间(大约一秒左右)。

以下工作正常,但问题是我的内存不足。 因此,当前一次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多行。

关于如何最好地接近这个的任何想法?

2 个答案:

答案 0 :(得分:5)

接下来ajax只有在当前的ajax调用完成后才会触发。下面的代码将帮助您实现它。

实现目标的步骤。

  • 创建一个数组并将数组中的DOM对象推送到所有div中。
  • 为ajax调用创建一个函数,并以递归方式调用它 格。
  • 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>

答案 1 :(得分: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)   
    });

这是一种hacky解决方案,但我认为它应该工作:) 这是一个使用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