如何建立朋友和喜欢的对象

时间:2012-03-12 17:17:06

标签: javascript facebook facebook-javascript-sdk

这部分是一个javascript技术问题。我正在尝试构建一个以facebook id为关键字的对象,以及一组喜欢作为值的对象。我的问题是在我最里面的函数中,我无法访问设置密钥所需的变量fbid。

如何在内部匿名函数的范围内访问fbid?

friendsLikes = [];
FB.api('/me/friends',function(friends){
    for(var i=0;i<friends.data.length;i++){
        var fbid = friends.data[i].id
        FB.api(fbid+'/likes',function(likes){
            if(likes.data.length>=1){
                            //this is where I build the object
                            //I cannot use fbid for the key :(
                console.log(likes.data.length);
            }
        })
    }
})

1 个答案:

答案 0 :(得分:4)

问题是在回调执行之前,fbid会在每次迭代时更新。

  • 循环浏览朋友列表
  • fbid设置为朋友的ID
  • 发起异步通话以获得该朋友的喜欢
  • 继续下一位朋友,直到我们遍历整个列表
  • 一段时间过去了
  • 结果从服务器返回并且回调开始执行。此时,fbid对于所有回调都是相同的 - 具体来说,它被设置为列表中最后一个朋友的ID。

以下是我如何捕获每次迭代的fbid

friendsLikes = [];
FB.api('/me/friends',function(friends){
    for(var i=0;i<friends.data.length;i++){
        var fbid = friends.data[i].id
        FB.api(fbid+'/likes', function(fbid) { return function(likes){
            if(likes.data.length>=1){
                            // `fbid` will be correct here
                console.log(likes.data.length);
            }
        }}(fbid));
    }
});

请注意,我们使用自执行函数并传递当前fbid。这将返回一个在范围内具有正确fbid的函数。


现在请注意你是如何做到的:这段代码的性能很糟糕,因为你要为每个朋友支付HTTP往返费用。请记住,浏览器只会在每个主机2-8个连接之间打开(取决于浏览器),所有这些调用都将转到 graph.facebook.com

如果有一个200的适度朋友列表和150ms的慷慨的往返时间,理论上最好的情况场景是~4秒。如果浏览器只进行2个并发连接并且我们有200ms的往返时间:20秒,事情很快就会走下坡路。

Facebook也很可能在某些时候限制你的速度。

相反,您需要使用Batch API

FB.api('/', 'POST', { batch: [
    { method: 'GET', relative_url: id+'/likes' },
    ...
] }, function(r) {
    // `r` will be an array of results for each item in `batch`
});