问题在于,ajax函数完成后,回调函数会在一段时间后发生。届时,数组索引将前进到
for循环的末尾(因此它指向数组的末尾)为未定义的值。该数组仍然存在,但是在调用完成函数时,索引已更改。
通常,将索引获取到成功处理程序中的技术是在函数闭包中捕获该索引,在该闭包中捕获该索引以供完成函数使用。
您可以使用以下内容替换成功处理程序,从而创建一个捕获索引值的闭包:
(function(index) { return function(dataJSON2) { resultArray = dataJSON2['data']; resultJSON += friendArray[index] + ":" + resultArray.length + ","; //alert(resultJSON); }}) (i);该外部函数执行并创建一个闭包,该闭包捕获i的值,并使它唯一可用于成功处理程序。当自身执行时,它将返回成功处理程序,该处理程序随后将传递给getJSON函数,以供稍后调用。但是,稍后调用它时,所需的值
i可通过自执行函数中的参数提供给成功处理程序。
这是考虑与回调一起使用的闭包的另一种方法。
- 任何函数在声明时都可以访问作用域内的所有变量,即使在父作用域中处于较高级别的变量也可以访问,即使该函数后来被称为回调。这实际上是许多其他语言所没有的javascript的巨大功能。
- 因此,如果我们希望变量在以后执行回调时可供回调函数使用,我们只需要以某种方式使该变量进入该回调函数的范围即可。
这是一个例子:
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。
- 如果变量在初始设置回调和调用回调之间没有变化,则非常简单。您可以只使用匿名函数声明,并且在稍后调用回调时,在定义匿名函数时可用的所有更高范围的变量仍将可用。
- 如果变量确实随着代码继续执行而发生更改,并且您想提供一个特定的值,则该变量现在在以后被调用时可供回调使用-这是在棘手的情况下。一个人所能做的就是创建一个函数,将这个变量传递给它,从而创建一个范围,使该变量具有所需的值,并且在该范围内不会随着其他代码的继续执行而改变。但是,因为我们要的是回调函数,而不仅仅是函数调用,所以我们必须以半古怪的方式将两者结合起来。我们进行函数调用并将其传递给所需的值。在该函数调用中,我们返回对回调函数的引用。这会适当地分配回调函数,但是会将回调函数放入一个捕获所需变量值的闭包中。更好的是 这个闭包对于该回调的特定实例是唯一的,因此对回调的每次使用都将拥有它自己的闭包,因此它是该变量的唯一值。我们为您的特定问题创建的关闭/回调就是一个例子。



