Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JSON输出在代码中未定义,但警报正常,这是作用域的问题吗?_Javascript_Json_Facebook_Scope - Fatal编程技术网

Javascript JSON输出在代码中未定义,但警报正常,这是作用域的问题吗?

Javascript JSON输出在代码中未定义,但警报正常,这是作用域的问题吗?,javascript,json,facebook,scope,Javascript,Json,Facebook,Scope,我正在使用Facebook graph API获取用户的好友列表,并根据模板和随机好友生成状态消息。如果我使用警报(response.data[0].name)而不是返回(响应)我的代码有效,我看到了第一个Facebook朋友的名字。当我在代码中进一步使用它时,它会抛出一个未定义的错误。经过几个小时的努力,我想我的作用域出现了一些问题,不再允许我使用响应,或者JSON格式有问题。我也尝试过使用jQuery的JSON解析,但没有得到任何额外的东西 shuffle = function(v){

我正在使用Facebook graph API获取用户的好友列表,并根据模板和随机好友生成状态消息。如果我使用
警报(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调用的工作方式就是这样。很好,我已经完成了这个答案,因为我现在已经开始工作了,根据需要重构我的所有函数,使其仅在异步之前或内部执行。我在上面的编辑中也发布了我的代码,所以任何有类似问题的人都可以从您的帮助中受益。