我在一个数组上遇到了一些困难,该数组(在异步调用之外)定义得很好,但是当我在一个异步请求(例如$ .getJSON)中调用其索引时,该数组的所有索引都未定义,但是 长度 是还是一样。这是我的代码。
我指的数组是 friendsArray
该数组在第二个“ $ .getJSON”调用期间具有正确的索引,但是在该函数的回调内部,其所有索引都变为未定义。由于数组是在方法范围内定义的,因此不应该保留其值吗?
if (response.status === 'connected') { var accessToken = $.trim(response.authResponse.accessToken); var hashArray = []; var friendArray = []; document.getElementById("statusCheck").innerHTML = accessToken; $.getJSON('https://graph.facebook.com/me/friends?access_token=' + accessToken, function(dataJSON){ hashArray = dataJSON['data']; for (var i = 0; i < hashArray.length; i++){ friendArray.push(hashArray[i]["id"]); } var resultJSON = "{"; var resultArray = []; for (var i = 0; i < friendArray.length; i++){ $.getJSON('https://graph.facebook.com/me/mutualfriends/' + friendArray[i] + "?access_token=" + accessToken, function(dataJSON2){ resultArray = dataJSON2['data']; resultJSON += friendArray[i] + ":" + resultArray.length + ","; //alert(resultJSON); }) if (i == friendArray.length - 1){ postArrayPopulation(resultJSON); } } });
}
问题在于,ajax函数完成后,回调函数会在一段时间后发生。届时,数组索引将前进到for循环的末尾(因此它指向数组的末尾)为未定义的值。该数组仍然存在,但是在调用完成函数时,索引已更改。
for
通常,将索引获取到成功处理程序中的技术是在函数闭包中捕获该索引,在该闭包中捕获该索引以供完成函数使用。
您可以使用以下内容替换成功处理程序,从而创建一个捕获索引值的闭包:
(function(index) { return function(dataJSON2) { resultArray = dataJSON2['data']; resultJSON += friendArray[index] + ":" + resultArray.length + ","; //alert(resultJSON); } }) (i);
该外部函数执行并创建一个闭包,该闭包捕获i的值,并使它唯一可用于成功处理程序。当自身执行时,它将返回成功处理程序,该处理程序随后将传递给getJSON函数,以供稍后调用。但是,稍后调用它时,所需的值i可通过自执行函数中的参数提供给成功处理程序。
i
这是考虑与回调一起使用的闭包的另一种方法。
这是一个例子:
function cycleOnOff(sel, cnt, delay) { var obj = $(sel); function next() { if (cnt-- > 0) { obj.toggle(); setTimeout(next, delay); } } next(); }
在这种情况下,该功能next()是一个回调setTimeout(),但该功能已完全进入到其父范围内的变量:sel,cnt,delay和obj。
next()
setTimeout()
sel
cnt
delay
obj