我不知道为什么getJSON中的'streamName [i]'返回'undefined'。它里面的所有内容都返回正确的值,但只有streamName返回未定义的值
var streamName = ['LCK1', 'ryan_clark', 'syndicate', 'riotgames', 'esl_csgo', 'Nightblue3', 'summit1g', 'imaqtpie', 'sodapoppin', 'captainsparklez'];
var nullLogo = "https://dummyimage.com/50x50/ecf0e7/5c5457.jpg&text=0x3F";
var name;
for (var i = 0; i < streamName.length; i++) {
var url = 'https://api.twitch.tv/kraken/streams/' + streamName[i] + '?callback=?';
$.getJSON(url, function(data) {
console.log(name);
if (data.stream == null) {
$('.streamersList').append('<div> <div class="logo"> <img src=' + nullLogo + '></div> <div class="nameStreamer">' + streamName[i] + '</div> <div class="state"> Offline </div></div>');
} else {
$('.streamersList').append('<div> <div class="logo"> <img src=' + data.stream.channel.logo + '></div> <div class="nameStreamer">' + streamName[i] + '</div> <div class="state">' + data.stream.channel.game + ' </div></div>');
}
});
}
最佳答案
因为$.getJSON
是异步函数,所以在回调运行时,i
将完成循环。由于当i
大于或等于streamName
的长度时循环中断,因此i
将尝试访问数组数组末尾streamName
中undefined
中的元素。
在这种情况下,i
之所以在每个回调实例内部包含10个,是因为作用域在JavaScript中起作用。据代码所知,i
与streamName
,nullLogo
和name
一起声明在函数的顶部。在循环中进行迭代时,i
的值会更改,并且该更改在函数内部的所有位置(包括尚未运行的回调内部)都可见。在它们运行时,i
将为10,因为它已到达循环末尾,这是回调将使用的值。
确保在i
函数中获取正确的$.getJSON
值的一种方法是将i
作为参数传递给立即调用的函数。这将有效地将i
的当前值绑定到参数index
,因此基于循环的迭代,使用index
将元素从数组中取出将具有正确的值。
for (var i = 0; i < streamName.length; i++) {
// note how i can be used here because this is synchronous, aka happening right now
var url = 'https://api.twitch.tv/kraken/streams/' + streamName[i] + '?callback=?';
(function(index) {
$.getJSON(url, function(data) {
// this is asynchronous (happens in the future), so i will have a different
// value by the time it is called, but index will have the correct value
console.log(name);
if (data.stream == null) {
$('.streamersList').append('<div> <div class="logo"> <img src='
+ nullLogo
+ '></div> <div class="nameStreamer">'
+ streamName[index]
+ '</div> <div class="state"> Offline </div></div>');
} else {
$('.streamersList').append('<div> <div class="logo"> <img src='
+ data.stream.channel.logo
+ '></div> <div class="nameStreamer">'
+ streamName[index]
+ '</div> <div class="state">'
+ data.stream.channel.game
+ ' </div></div>');
}
});
})(i);
}