Javascript JSON输出在代码中未定义,但警报正常,这是作用域的问题吗?
我正在使用Facebook graph API获取用户的好友列表,并根据模板和随机好友生成状态消息。如果我使用Javascript JSON输出在代码中未定义,但警报正常,这是作用域的问题吗?,javascript,json,facebook,scope,Javascript,Json,Facebook,Scope,我正在使用Facebook graph API获取用户的好友列表,并根据模板和随机好友生成状态消息。如果我使用警报(response.data[0].name)而不是返回(响应)我的代码有效,我看到了第一个Facebook朋友的名字。当我在代码中进一步使用它时,它会抛出一个未定义的错误。经过几个小时的努力,我想我的作用域出现了一些问题,不再允许我使用响应,或者JSON格式有问题。我也尝试过使用jQuery的JSON解析,但没有得到任何额外的东西 shuffle = function(v){
警报(response.data[0].name)代码>而不是返回(响应)代码>我的代码有效,我看到了第一个Facebook朋友的名字。当我在代码中进一步使用它时,它会抛出一个未定义的错误。经过几个小时的努力,我想我的作用域出现了一些问题,不再允许我使用响应,或者JSON格式有问题。我也尝试过使用jQuery的JSON解析,但没有得到任何额外的东西
shuffle = function(v){
for(var j, x, i = v.length; i; j = parseInt(Math.random() * i), x = v[--i], v[i] = v[j], v[j] = x);
return v;
};
function getFriends() {
FB.login(function(response) {
if (response.session && response.perms) {
FB.api('/me/friends', function(response) {
return response;
});
}
} , {perms:'publish_stream'});
};
function selectFriend(){
var friends = getFriends();
friends = friends.data[0];
var findex = friends.length
var randomNumber = (Math.floor( Math.random() * 10 ) % findex);
return(friends[randomNumber].name);
};
function process(status){
status = status[0].toString();
var cindex = status.indexOf("{{friend}}");
while (cindex != -1){
status = status.replace("{{friend}}",selectFriend());
cindex = status.indexOf("{{friend}}");
}
return(status);
};
function newStatus(){
var status = [
"This status is named {{friend}}",
"This status loves {{friend}} but likes {{friend}} too.",
"This status goes by {{friend}} but you can call it {{friend}} if you like.",
"This status hates {{friend}}"
];
status = shuffle(status);
$('#status').text(process(status));
}
代码以单击时调用newStatus()开始
编辑:下面是我如何在jfriend00的回答之后重构代码的方法:
shuffle = function(v){
for(var j, x, i = v.length; i; j = parseInt(Math.random() * i), x = v[--i], v[i] = v[j], v[j] = x);
return v;
};
function newStatus(){
var status = [
"This status is named {{friend}}",
"This status loves {{friend}} but likes {{friend}} too.",
"This status goes by {{friend}} but you can call it {{friend}} if you like.",
"This status hates {{friend}}"
];
status = shuffle(status);
status = status[0].toString();
FB.login(function(response) {
if (response.session && response.perms) {
FB.api('/me/friends', function(response) {
var friends = response.data;
var findex = friends.length
var cindex = status.indexOf("{{friend}}");
while (cindex != -1){
var randomNumber = (Math.floor( Math.random() * 10 ) % findex);
var name = friends[randomNumber].name;
status = status.replace("{{friend}}",name);
cindex = status.indexOf("{{friend}}");
}
$('#status').text(status);
});
}
} , {perms:'publish_stream'});
}
问题可能是对FBAPI的调用是不同步的。这意味着当您调用FB.api()时,它将启动对FB的ajax调用。当ajax调用完成时,您的其他代码将继续运行。事实上,您对getFriends的调用完成,其余的selectFriend()也在FB ajax调用完成之前运行
然后,当fbapi调用完成时,它调用completion函数(可能在您放置警报的地方)。在代码中,在完成函数中没有执行任何有意义的操作。您只是返回了带有
return response;
但是,这并没有做任何有用的事情。该返回值不是从getFriends()函数返回的。这是对ajax引擎内部某些内容的回归
如果您想对FB.api(
)响应执行一些有用的操作,则需要运行该代码或从FB.api()
调用中指定的完成函数调用该代码
您必须执行类似以下伪代码的操作:
function getFriends() {
FB.login(function(response) {
if (response.session && response.perms) {
FB.api('/me/friends', function(response) {
var friends = response.data[0];
var findex = friends.length
var randomNumber = (Math.floor( Math.random() * 10 ) % findex);
var name = friends[randomNumber].name;
// now continue on with whatever you want to do with the random friend info
// you cannot just return data from this callback, you have to actually carry
// out whatever you were going to do with the data here
});
}
} , {perms:'publish_stream'});
};
function selectFriend(){
getFriends();
// the getFriends() function is asynchronous and the FB.api() call has not yet
// completed so we can't do anything here yet as we have to wait for the
// FB.api() call to finish first.
};
首先,谢谢你抽出时间,我很感激。我明白你所说的关于计时的内容,以及为什么在数据准备好之前调用下一个函数,导致在调用之外失败。根据您的建议,基本上将逻辑移动到API调用中,我假设可以达到预期的结果,但我仍然要处理从API调用返回它的问题。我可以随便说出一个朋友的名字(通话的目的),但这仍然会太快,无法在replace循环中使用。从逻辑上讲,你要做的是打FB电话,然后再不做任何其他工作。当FB调用完成并且您现在拥有FB数据时,您将从FB调用完成后调用一个函数,该函数将完成所有其他工作,因为现在您拥有FB数据。不能在一个循环中进行API调用,并希望能够在循环中使用结果。这是异步编程。有时这很痛苦,但浏览器中ajax调用的工作方式就是这样。很好,我已经完成了这个答案,因为我现在已经开始工作了,根据需要重构我的所有函数,使其仅在异步之前或内部执行。我在上面的编辑中也发布了我的代码,所以任何有类似问题的人都可以从您的帮助中受益。