Ajax请求在另一个内部

时间:2018-04-22 20:12:06

标签: javascript jquery ajax loops

我为我的战场1战队制作了一个网站,在这个网站上我想展示这个战队中的每个玩家以及他们的一些游戏中的统计数据。 播放器列表存储在数据库中,我将从此api获取统计信息 。这意味着我将首先使用ajax从数据库中获取播放器列表,然后循环遍历它们以通过该循环中的第二个ajax调用获取播放器统计信息。

这一切听起来都很有趣,直到我运行我的代码,有时不是所有的请求都成功,每当我试图显示一个显示名称时,它总会显示最后一次调用的那个。

这是我的代码:

$(document).ready(function() {
  $.ajax({
    url: 'playerlist.php',
    method: 'POST',
    data: {
      playercheck: 1,
    },
    success: function(response) {
      var len = response.length;
      for (var i = 0; i < len; i++) {
        var psnid = response[i].psnid;

        // second ajax 

        var request = new XMLHttpRequest();

        request.open('GET', 'https://battlefieldtracker.com/bf1/api/Stats/BasicStats?platform=2&displayName=' + psnid);

        request.setRequestHeader('TRN-Api-Key', '125a7cbe-1bbe-45d4-9f70-3aa838fc7535');

        request.onreadystatechange = function() {
          if (this.readyState === 4 && this.status == 200) {
            console.log('Status:', this.status);
            console.log('Headers:', this.getAllResponseHeaders());
            console.log('Body:', this.responseText);
            var result = JSON.parse(request.responseText);

            console.log(result);
            $("#userTable").append(result['profile']['displayName']);
          }
        };

        request.send();

        // end second

      }
    },
    dataType: "json"
  });
});

如果你们能告诉我是什么导致了这个并帮助我找到解决方案,那就太好了。 提前谢谢!

2 个答案:

答案 0 :(得分:1)

这很可能是一个可变范围问题。在JavaScript中,带有var的变量声明被“提升”到包含函数的顶部。此外,变量的范围是函数,而不是for循环。

因此,虽然看起来每个for循环迭代都应该创建一个完全独立的request实例,但这不是正在发生的事情。在onreadystatechange事件触发时,您的request值可能已更改。

有两种方法可以解决这个问题。首先,使用es6 JS的新letconst变量声明,范围是不同的。因此,如果您不需要在旧浏览器中使用此功能,则可以从var request更改为let request,它应该可以正常工作。

如果无法做到这一点,您需要想出一种限制request变量“范围”的方法,例如将请求代码放入函数中,然后调用函数来自你的for循环。

答案 1 :(得分:0)

试试这个重构版本:

$(document).ready(function() {
  $.ajax({
    url: "playerlist.php",
    method: "POST",
    data: {
      playercheck: 1
    },
    success: function(response) {
      getStats(response);
    },
    dataType: "json"
  });
});

function getStats(stats) {
  var len = stats.length;
  for (var i = 0; i < len; i++) {
    getStatInfo(stats[i].psnid);
  }
}

function getStatInfo(psnid) {
  var request = new XMLHttpRequest();

  request.open(
    "GET",
    "https://battlefieldtracker.com/bf1/api/Stats/BasicStats?platform=2&displayName=" +
      psnid
  );

  request.setRequestHeader(
    "TRN-Api-Key",
    "125a7cbe-1bbe-45d4-9f70-3aa838fc7535"
  );

  request.onreadystatechange = function() {
    if (this.readyState === 4 && this.status == 200) {
      console.log("Status:", this.status);
      console.log("Headers:", this.getAllResponseHeaders());
      console.log("Body:", this.responseText);
      var result = JSON.parse(request.responseText);

      console.log(result);
      $("#userTable").append(result["profile"]["displayName"]);
    }
  };

  request.send();
}