【问题标题】:Ajax inside a for loop executing all at oncefor循环中的Ajax一次执行
【发布时间】:2013-05-29 06:02:51
【问题描述】:

好的,所以我们有这个代码:

var players = '<?php echo $players ?>';
for (var i = 0; i < 2; i++)
{
  $.ajax({
  type: "POST",
  url: "url...",
  data: { currentplayer: i, players: players },
  dataType: 'json',
  cache: false,
  timeout:60000,
  success: function(output){
  <?php echo write_log("output[\"message\"]", "output[\"class\"]") ?>

  $.ajax({
    type: "POST",
    url: "url...",
    data: { currentplayer: i, players: players },
    dataType: 'json',
    cache: false,
    timeout:60000,
    success: function(output){
           <?php echo write_log("output[\"message\"]", "output[\"class\"]") ?>
        }
      });
    }
  });
}

现在问题可能听起来很简单,但我找不到解决方案。

显然,第一个成功函数中的第二个 Ajax 调用发生在第一个完成之后。这真的很快,因为它只是一个 MySQL 请求。

现在秒数更长了,因为它是 PHP 文件中的一个循环(foreach 和 while)。现在它会触发第一个请求,然后是秒,然后它再次执行相同的操作(指定的循环 1 次)。现在它不会等待请求完成来继续循环。

问题:我不希望请求同时出现。
我希望这样: 循环开始:第一个 Ajax 调用完成 -> 第二个 Ajax 调用完成 -> 循环 -> 第三个 Ajax 调用完成 -> 第四个 Ajax 调用完成

基本上一个接一个。

另外:async: false 不是一个选项,因为它会冻结浏览器,我需要在每次 Ajax 查询后显示实时反馈。

有什么解决办法吗?

【问题讨论】:

  • 我不明白 AJAX 与嵌入式 PHP 的意义何在...
  • 顺便说一句,您的 i 变量可能在成功函数中丢失了,您需要在这里关闭。整个事情看起来不对劲。 PHP中的AJAX中的AJAX???我会从头开始使用良好的做法,即。分离你的 JS 和 PHP 代码,并可能使用 Promise 分别处理这些 AJAX 调用,更好地组织。
  • 在 ajax 调用之前,您不能真的期望 PHP 代码执行... PHP 是服务器端,您的 JS 是客户端。
  • 我在模态框内使用此代码,但如果我在 Ajax 之外使用 PHP,它将不会打开模态框,因为模态框仅在 PHP 准备好后才完成加载。而且由于您不能在文档加载后延迟 PHP 开始执行,这是我唯一的选择。

标签: php javascript jquery ajax for-loop


【解决方案1】:

在一个函数中执行它,并在 2 ajax 调用成功后再次调用该函数。还为当前循环中的当前玩家计数设置一个全局变量。

var players = '<?php echo $players ?>';

var global_current_player = 0;

function doAjax(current_player) {
    $.ajax({
        type: "POST",
        url: "url...",
        data: { currentplayer: current_player, players: players },
        dataType: 'json',
        cache: false,
        timeout:60000,
        success: function(output){

            $.ajax({
                type: "POST",
                url: "url...",
                data: { currentplayer: current_player, players: players },
                dataType: 'json',
                cache: false,
                timeout:60000,
                success: function(output){
                    global_current_player++;
                    if (global_current_player < 2) {
                        doAjax(global_current_player);
                    }
                }
            });
        }
    });   
}

doAjax(global_current_player);

所以这个函数是递归的,只在条件global_current_player &lt; 2之前有效

PS:我没有执行这个函数,但是这个逻辑应该可以工作。

【讨论】:

    【解决方案2】:

    要解决上述问题,请尝试在第一个 ajax 成功函数中获取条件,并将第二个 ajax 代码放在成功函数的站点之外。

    【讨论】:

      【解决方案3】:

      您可以使用while 循环而不是for 循环,并仅在ajax 调用返回成功(或错误)时递增它

      尝试:

          var i =0;
          execute = True
         while(i<2){
         if(execute){
            execute = False
            $.ajax({
               .. your ajax code ...
              success:function(){
                 execute = True
                 i++
                }
             error:function(){
              execute = True
              i++
              } 
           })
          }
        }
      

      这样,只有当 ajax 返回某些内容时,您的 while 循环才会增加。到那时,它将继续运行 i 的先前值,并且由于 execute 为 False,ajax 只会命中一次

      【讨论】:

      • 你仍然需要一个闭包来在每次迭代中传递 i 的正确值,尽管这不能解决问题并且你缺少分号、逗号,并且你有一个隐式全局变量。
      • 你可以用 for 循环做同样的事情,正如@elclanrs 指出你需要关闭循环变量。此外,由于您可以使用递归,因此没有必要让该循环保持忙碌。
      【解决方案4】:

      你可以使用递归:

      function sync(i) {
        if (i < 2) {
          $.ajax({...,
            success: function(options) {
              ...
              $.ajax({...,
                success: function(options) {
                  ...
                  sync(i+1);
                }
              });
            }
          });
        }
      }
      sync(0);
      

      【讨论】:

        【解决方案5】:

        试试这个。我使用 True 或 False 标志“prevAjaxCmpltd”控制了您的 AJAX 请求的执行。

        var players = '<?php echo $players ?>';
        var i =0;
        var prevAjaxCmpltd = True;
        while (i < 2)
        {
          if(prevAjaxCmpltd){
              i++;
              prevAjaxCmpltd = False;
              $.ajax({
                  type: "POST",
                  url: "url...",
                  data: { currentplayer: i, players: players },
                  dataType: 'json',
                  cache: false,
                  timeout:60000,
                  success: function(output){
                      $.ajax({
                          type: "POST",
                          url: "url...",
                          data: { currentplayer: i, players: players },
                          dataType: 'json',
                          cache: false,
                          timeout:60000,
                          success: function(output){
                              prevAjaxCmpltd = True;
                          }
                      });
                  }
              });
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-11-22
          • 1970-01-01
          • 1970-01-01
          • 2018-06-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多