迭代和执行$ .ajax opertaion时的数组元素不确定



$(document).ready(function() {
  loadStreamInfo();
  displayAll();
});
var allStreamInfo = [{ "user": "ogaminglol"}, { "user": "faceittv" }, { "user": "twitch"}, { "user": "hearthstonesea"}, {  "user": "stephensonlance"}, {"user": "aegabriel" }];
function loadStreamInfo() {
  for (var i = 0; i < 6; i++) {
    $.ajax({
      url: ("https://wind-bow.gomix.me/twitch-api/streams/" + allStreamInfo[i].user),
      jsonp: "callback",
      dataType: "jsonp",
      success: function(data) {
        if (data.stream == null) {
          allStreamInfo[i]["status"] = "offline";
        } else {
          allStreamInfo[i]["status"] = "online";
        }
      }
    });
  }
  for (var i = 0; i < 6; i++) {
    $.ajax({
      url: ("https://wind-bow.gomix.me/twitch-api/channels/" + allStreamInfo[i].user),
      jsonp: "callback",
      dataType: "jsonp",
      success: function(data) {
        allStreamInfo[i]["logo"] = data.logo;
        allStreamInfo[i]["gameName"] = data.game;
        allStreamInfo[i]["views"] = data.views;
        allStreamInfo[i]["followers"] = data.followers;
        allStreamInfo[i]["url"] = data.url;
      }
    });
  }
}
function displayAll() {
  for (var i = 0; i < 6; i++) {
    var outString = "";
    outString += "<div class='item'>";
    outString += "<img src='" + allStreamInfo[i].logo + "' alt='logo'>";
    outString += "<a href='" + allStreamInfo[i].url + "'><span id='gameName'>" + allStreamInfo[i].gameName + "</span></a>";
    outString += "<span id='state'>" + allStreamInfo[i].status + "</span>";
    outString += "<span id='views-block'>Views:<span id='view'>" + allStreamInfo[i].views + "</span></span>";
    outString += "<span id='follow-block'>Followers:<span id='followed'>" + allStreamInfo[i].followers + "</span></span>";
    outString += "</div>";
    $("#result").append(outString);
  }
}
body {
  padding: 40px;
  ;
}
.toggle-button {
  width: 400px;
  color: white;
  height: 100px;
  text-align: center;
  margin: 0 auto;
}
.all {
  background-color: #6699CC;
  width: 30%;
  height: 70px;
  line-height: 70px;
  border-right: 2px solid grey;
  display: inline;
  float: left;
  cursor: pointer;
}
.online {
  cursor: pointer;
  line-height: 70px;
  background-color: cadetblue;
  border-right: 2px solid grey;
  width: 30%;
  height: 70px;
  display: inline;
  float: left;
}
.offline {
  cursor: pointer;
  background-color: darkorange;
  line-height: 70px;
  width: 30%;
  height: 70px;
  display: inline;
  float: left;
}
#result {
  margin-top: 30px;
}
.item {
  width: 500px;
  height: 70px;
  margin: 5px auto;
  background-color: #666699;
  border-left: 4px solid red;
  color: whitesmoke;
  /*border: 2px solid red;*/
}
a {
  text-decoration: none;
}
img {
  width: 50px;
  height: 50px;
  margin-top: 10px;
  margin-left: 20px;
  margin-right: 21px;
}
span#gameName,
span#views-block,
span#state,
span#follow-block {
  position: relative;
  bottom: 18px;
}
span#gameName,
span#state,
span#views-block {
  margin-right: 21px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<div class="toggle-button">
  <div class="all" onclick="displayAll()">All</div>
  <div class="online" onclick="displayOnline()">Online</div>
  <div class="offline" onclick="displayOffline()">Offline</div>
</div>
<div id="result">
</div>

我想在JSON对象中动态添加属性。我已经阅读了post1和post2。但是为什么我有未定义的财产?allStreamInfo[i]["prop"] = "value"不是将属性添加到对象的方法吗?在调试窗口中,有Uncaught TypeError: Cannot set property 'logo' of undefined(…)。我有检查API调用,它进行得很好。看来我没有定义道具,但是不是动态添加道具的方法吗?

当您使用$.ajax()时,这是循环中的无链操作。当获得ajax操作的结果i的结果将没有启动的值时,allStreamInfo[i]undefined

您可以使用关闭,以维护i的值,直到AJAX操作完成

封闭是指函数,指的是独立(自由)变量(本地使用但在封闭范围中定义的变量)。换句话说,这些功能"记住"了它们创建的环境。

for (var i = 0; i < 6; i++) {
    (function(j) {
        $.ajax({
            url: "https://wind-bow.gomix.me/twitch-api/streams/" + allStreamInfo[j].user,
            jsonp: "callback",
            dataType: "jsonp",
            success: function(data) {
                allStreamInfo[j]["status"] = data.stream == null ? "offline" : "online";
            }
        });
    })(i);
}

确实读取javaScript闭合循环 - 简单实践示例

好吧,最重要的是,您的代码对我来说似乎不正确。 $.ajax返回承诺,这是未来的对象。

当解决这些承诺时,

i变为 6i == 6时循环终止)。因此,在成功回调中,表达式变为 allStreamInfo[6]["status"]

由于allStreamInfo[6]是您的代码中的undefined,因此错误。

您处理诺言尝试此代码

$(document).ready(function() {
  loadStreamInfo();
});
var allStreamInfo = [{
  "user": "ogaminglol"
}, {
  "user": "faceittv"
}, {
  "user": "twitch"
}, {
  "user": "hearthstonesea"
}, {
  "user": "stephensonlance"
}, {
  "user": "aegabriel"
}];
var i = 0;
function loadStreamInfo() {
  $.ajax({
    url: ("https://wind-bow.gomix.me/twitch-api/channels/" + allStreamInfo[i].user),
    jsonp: "callback",
    dataType: "jsonp",
    success: function(data) {
      if (data.stream == null) {
        allStreamInfo[i].status = "offline";
      } else {
        allStreamInfo[i].status = "online";
      }
      allStreamInfo[i].logo = data.logo;
      allStreamInfo[i].gameName = data.game;
      allStreamInfo[i].views = data.views;
      allStreamInfo[i].followers = data.followers;
      allStreamInfo[i].url = data.url;
      i++;
      if (i < allStreamInfo.length)
        loadStreamInfo();
      else
        displayAll();
    }
  });
}
function displayAll() {
  for (var i = 0; i < 6; i++) {
    var outString = "";
    outString += "<div class='item'>";
    outString += "<img src='" + allStreamInfo[i].logo + "' alt='logo'>";
    outString += "<a href='" + allStreamInfo[i].url + "'><span id='gameName'>" + allStreamInfo[i].gameName + "</span></a>";
    outString += "<span id='state'>" + allStreamInfo[i].status + "</span>";
    outString += "<span id='views-block'>Views:<span id='view'>" + allStreamInfo[i].views + "</span></span>";
    outString += "<span id='follow-block'>Followers:<span id='followed'>" + allStreamInfo[i].followers + "</span></span>";
    outString += "</div>";
    $("#result").append(outString);
  }
}
body {
  padding: 40px;
  ;
}
.toggle-button {
  width: 400px;
  color: white;
  height: 100px;
  text-align: center;
  margin: 0 auto;
}
.all {
  background-color: #6699CC;
  width: 30%;
  height: 70px;
  line-height: 70px;
  border-right: 2px solid grey;
  display: inline;
  float: left;
  cursor: pointer;
}
.online {
  cursor: pointer;
  line-height: 70px;
  background-color: cadetblue;
  border-right: 2px solid grey;
  width: 30%;
  height: 70px;
  display: inline;
  float: left;
}
.offline {
  cursor: pointer;
  background-color: darkorange;
  line-height: 70px;
  width: 30%;
  height: 70px;
  display: inline;
  float: left;
}
#result {
  margin-top: 30px;
}
.item {
  width: 500px;
  height: 70px;
  margin: 5px auto;
  background-color: #666699;
  border-left: 4px solid red;
  color: whitesmoke;
  /*border: 2px solid red;*/
}
a {
  text-decoration: none;
}
img {
  width: 50px;
  height: 50px;
  margin-top: 10px;
  margin-left: 20px;
  margin-right: 21px;
}
span#gameName,
span#views-block,
span#state,
span#follow-block {
  position: relative;
  bottom: 18px;
}
span#gameName,
span#state,
span#views-block {
  margin-right: 21px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<div class="toggle-button">
  <div class="all" onclick="displayAll()">All</div>
  <div class="online" onclick="displayOnline()">Online</div>
  <div class="offline" onclick="displayOffline()">Offline</div>
</div>
<div id="result">
</div>

最新更新