这部分是一个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);
}
})
}
})
答案 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`
});