看看下面的实现。我已将其分解为多个功能以分隔每个步骤。在处理循环和回调时,跟踪定义匿名函数的范围变得非常重要。
从理论上讲,您可以像写的那样在单行中完成所有操作
……但是随着您越来越深入地使用嵌套回调,它会变得非常非常混乱。
一种解决方案是使每个函数中的每个变量 100% 全局化,这样只i
需要一个封闭的引用。不过,这并不是很漂亮。
查看每个函数并记下每个步骤调用的函数(或回调的闭包)中有哪些参数。它们都是必需的(无论您以这种方式将它们分开,还是通过单列中的闭包或其他方式)。
在 Facebook 开发人员沙箱内(第一次使用 API),以下内容对我来说效果很好。
这些日志是为了让我了解数据是如何输出的,并保持基本的堆栈跟踪。
var userList = [],
userCount = 0;
function getfriends () {
//console.log("getFriends");
var url = "/me/friends";
FB.api(url, function (response) {
if (response.error && response.error.message) { return false; }
userList = userList.concat(response.data);
userCount = response.data.length;
compareAllFriends();
});
}
function compareAllFriends () {
//console.log("compareAllFriends");
var i = 0, l = userCount, userID;
for (; i < l; i += 1) {
userID = userList[i].id;
compareFriendsWith (i, userID);
}
}
function compareFriendsWith (i, id) {
//console.log("compareFriendsWith", i, id);
var path = "/me/mutualfriends/",
url = path + id + "/";
FB.api(url, (function (i) {
return function (response) {
//console.log(i, response);
var numFriends = (response.data) ? response.data.length : 0;
setMutualFriends(i, numFriends);
userCount -= 1;
//console.log(userCount);
if (userCount === 0) {
display_results();
//console.log("DISPLAYING");
}
};
}(i)));
}
function setMutualFriends (i, friendcount) { userList[i].mfCount = friendcount; }