我在以下问题上被困了太长时间,我真的需要考虑我在Javascript中关于变量范围和回调函数的理论知识。而不是快速解决我的特定问题,而是试图解释我的问题背后的理论的广义答案是首选。这是代码(不起作用)(哦,它使用jQuery的$ .getJSON)。
function getStreamerStatus(streamer) {
var channelurl = "https://api.twitch.tv/kraken/channels/";
var streamurl = "https://api.twitch.tv/kraken/streams/";
var temporary = {
status: "",
game: "",
picture: "",
name: streamer,
link: "https://www.twitch.tv/" + streamer
};
$.getJSON(streamurl + streamer, createCallback(temporary));
$.getJSON(channelurl + streamer, createCallback(temporary));
return temporary;
}
经过一些搜索,我使用了“createCallback()”函数,试图让“临时”对象对回调函数可见。
function createCallback(tmpobj) {
return function(json) {
//get's some information and stores it in the object passed as tmpobj
filterOut(json, tmpobj);
};
}
最后在main函数中我有一个名为twitch streamers的数组,每个名称调用“getStreamerStatus()”函数,返回的对象存储在数组中。
function TwitchInit() {
var channels = [/*filled with strings of streamer names*/];
var response = []; //array with objects with all the information
for(var i = 0; i < channels.length; i++) {
response.push(getStreamerStatus(channels[i]));
}
parseContent(response); //not relevant for now
//for debugging
for(var j = 0; j < response.length; j++) {
console.log("--responseArray with Objects--");
for(var prop in response[j]) {
if(response[j].hasOwnProperty(prop)) {
console.log(prop + ": " + response[j][prop]);
}
}
}
}
这里的问题是,如果我将对象记录到控制台,只有对象的“链接”和“名称”属性具有一些内容,而其他属性应该由“filterOut()”写入功能始终保持空白。根据控制台,与Twitch服务器的通信很好,我可以从控制台读取响应头/对象,以便排除。并且由于每个日志到控制台的“名称”和“链接”属性也不同,这意味着每次创建一个新对象都很好。这让我得出这样的结论:“临时”对象仍然以某种方式对$ .getJSON内部的回调函数不可见,尽管我尝试使用“createCallback()”使对象对“filterOut()”函数可见。我在JavaScript中找到了很多关于变量范围的信息,但到目前为止它还没有帮助我解决我的问题。我不知道我在这里做错了什么,我开始感到沮丧。我真的希望有人能在这里启发我。
答案 0 :(得分:0)
我认为这里的闭包没有问题,唯一的问题是你的getStreamerStatus函数会执行异步任务,但会直接返回一个值,并在不等待异步调用(getJSON)完成的情况下使用它。
尝试将调试日志放在setTimeout中,延迟时间为几秒;)
为了做得更好,你应该重写你的getStreamerStatus,只在getJSON调用完成后返回数据,而不是之前,使用回调作为参数,或者返回一个promise。
或者你应该有一些东西(即:一个事件)来告诉你的函数调用已经完成,并且它可以处理结果。