以下是将两个JSON对象推入数组后的数据示例。访问数据很简单。如果我想访问说明徽标,我可以使用example[0].channels.logo
。但是,尝试从JSONP调用访问同一个数组时,结果为undefined
。
let example =
[
{
"channels": {
"mature": false,
"status": "Some GoLang Today #go #golang #youtube",
"broadcaster_language": "en",
"display_name": "FreeCodeCamp",
"game": "Creative",
"language": "en",
"_id": 79776140,
"name": "freecodecamp",
"created_at": "2015-01-14T03:36:47Z",
"updated_at": "2018-04-11T22:33:06Z",
"partner": false,
"logo": "https://static-cdn.jtvnw.net/jtv_user_pictures/freecodecamp-profile_image-d9514f2df0962329-300x300.png",
"video_banner": "https://static-cdn.jtvnw.net/jtv_user_pictures/freecodecamp-channel_offline_image-b8e133c78cd51cb0-1920x1080.png",
"profile_banner": "https://static-cdn.jtvnw.net/jtv_user_pictures/freecodecamp-profile_banner-6f5e3445ff474aec-480.png",
"profile_banner_background_color": null,
"url": "https://www.twitch.tv/freecodecamp",
"views": 210806,
"followers": 11582,
"_links": {
"self": "https://api.twitch.tv/kraken/channels/freecodecamp",
"follows": "https://api.twitch.tv/kraken/channels/freecodecamp/follows",
"commercial": "https://api.twitch.tv/kraken/channels/freecodecamp/commercial",
"stream_key": "https://api.twitch.tv/kraken/channels/freecodecamp/stream_key",
"chat": "https://api.twitch.tv/kraken/chat/freecodecamp",
"features": "https://api.twitch.tv/kraken/channels/freecodecamp/features",
"subscriptions": "https://api.twitch.tv/kraken/channels/freecodecamp/subscriptions",
"editors": "https://api.twitch.tv/kraken/channels/freecodecamp/editors",
"teams": "https://api.twitch.tv/kraken/channels/freecodecamp/teams",
"videos": "https://api.twitch.tv/kraken/channels/freecodecamp/videos"
},
"delay": null,
"banner": null,
"background": null
}
},
{
"streams": {
"stream": null,
"_links": {
"self": "https://api.twitch.tv/kraken/streams/freecodecamp",
"channel": "https://api.twitch.tv/kraken/channels/freecodecamp"
}
}
}
]
// all of these work
console.log(example);
console.log(example[0]);
console.log(example[0].channels);
console.log(example[0].channels);
这是处理每个JSONP请求的函数 - 每个响应都存储在一个对象中,其属性名称为已定义的路由参数。
const jsonpCall = (route, channel) => {
let result = {};
$.ajax({
url: `https://wind-bow.gomix.me/twitch-api/${route}/${channel}?callback=?`,
dataType: 'jsonp',
success: function(data){
result[route] = data;
},
});
return result;
};
这是一个函数调用,它将两个返回的对象分组到一个数组中,然后将该数组移交给另一个函数以对对象进行排序/缩小。
const channelsToSearch = ["freecodecamp","nba","shroud"];
channelsToSearch.forEach(channel => {
const channelData = [];
channelData.push(jsonpCall("channels",channel));
channelData.push(jsonpCall("streams",channel));
console.log(sortData(channelData));
});
这就是问题的开始。此函数获取两个对象的数组,并开始创建要返回的新对象。它无法访问该对象。
const sortData = arr => {
console.log(arr); // okay!
console.log(arr[0]); // okay!
console.log(arr[0].channels); // undefined?
const obj = {};
obj.logo = arr[0].channels.logo;
obj.displayName = arr[0].channels["display_name"];
arr[1].streams.stream === null ? obj.status = "Offline" : obj.status = arr[1].streams.stream.channel.status;
return obj;
};
我不确定从日志中的差异中辨别出什么。
前三个日志来自示例日志。
最后三个日志来自sortData函数。
最终错误来自sortData函数中的obj.logo = arr[0].channels.logo;
行。
答案 0 :(得分:0)
此代码的问题在于以下部分:
const jsonpCall = (route, channel) => {
let result = {};
$.ajax({
url: `https://wind-bow.gomix.me/twitch-api/${route}/${channel}?callback=?`,
dataType: 'jsonp',
success: function(data){
result[route] = data;
},
});
return result;
};
ajax调用是异步的,但它被视为同步。这就是为什么它将返回{}
的结果,因为success
函数执行得晚。如果您尝试在console.log
内添加success
功能,您会看到它会显示在sortData.
内的日志之后这就是为什么在您的日志中显示Array [{}, {}]
都是空的。
解决此问题的一种方法是异步编码:
确保jsonpCall
返回Promise
。默认情况下,$.ajax()
会返回Promise
。
在这部分代码中:
channelsToSearch.forEach(channel => {
const channelData = [];
channelData.push(jsonpCall("channels",channel));
channelData.push(jsonpCall("streams",channel));
console.log(sortData(channelData));
});
您必须使用.then
回调异步处理它。
请看这个小提琴:https://jsfiddle.net/kLnsf1gn/2。我在其中添加了评论以便于理解。