【问题标题】:Ajax request inside another one另一个里面的Ajax请求
【发布时间】:2018-04-22 20:12:06
【问题描述】:

我正在为我的战场 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"
  });
});

如果你们能告诉我造成这种情况的原因并帮助我找到解决方案,那就太好了。 提前致谢!

【问题讨论】:

标签: javascript jquery ajax loops


【解决方案1】:

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

因此,虽然看起来似乎每个 for 循环迭代都应该创建一个完全独立的 request 实例,但事实并非如此。当onreadystatechange 事件触发时,您的request 值可能已经改变。

有两种方法可以解决这个问题。一、使用es6 JS新的letconst变量声明,作用域不同。因此,如果您不需要它在旧版浏览器中工作,您只需将var request 更改为let request,它应该可以工作。

如果这不可能,您需要想出一种方法来限制request 变量的“范围”,例如将您的请求代码放入一个函数中,然后从内部调用该函数你的 for 循环。

【讨论】:

  • 实际上,进一步思考,由于您在创建 request 后不会“改变”它,因此使用 const request 而不是 let 可能会更好。
  • 非常感谢,我没想到会这么简单!
  • 不客气。如果您对答案感到满意,除了点赞之外,您介意接受它吗?
  • 仅供参考,这个问题is a duplicate
【解决方案2】:

试试这个重构版本:

$(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();
}

【讨论】:

  • 就像第一个答案一样,这个解决方案就像一个魅力。但是您能否详细说明您出于什么原因进行了哪些更改?
  • @CheapGamer 因为request 变量的作用域(request 变量被覆盖),而且我发现开始重构代码更容易,所以我可以更好地理解它的部分:)。
猜你喜欢
  • 2016-04-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 2020-03-26
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 2012-12-21
相关资源
最近更新 更多