javascript – 将额外的参数传递给jQuery getJSON()成功回调函数

我以前从来没有使用回调函数,所以我可能会犯下一个完全愚蠢的错误。我认为我有点了解这里的问题,但不是如何解决这个问题。

我的代码(有点简化)是:

for (var i = 0; i < some_array.length; i++) {
    var title = some_array[i];
    $.getJSON('some.url/' + title, function(data) {
        do_something_with_data(data, i);
    }

现在据我所知,这个匿名函数只有在getJSON()接收到数据时才会被调用。但是到目前为止,我没有我需要的价值。或者,就我的观察而言,循环完成后会有最后的价值(不应该超出范围)?

因此,如果数组的大小为6,那么do_something_with_data()将被调用五次,值为5。

现在我想,只是通过我的匿名功能

function(data, i) { }

但这似乎不可能。我现在没有定义

你需要了解什么是关闭。在JavaScript中,在函数内部使用在外部上下文(外部函数或全局)中定义的变量时,会围绕该变量创建一个闭包,该变量保留变量实例化,并使函数在每次都继续引用时被调用(以及任何其他功能实例与项目上的闭包)。

因为原始变量仍然被实例化,如果您在代码中的任何地方更改该变量的值,当函数稍后运行时,它将具有当前更改的值,而不是该函数首次创建时的值。

在我们解决使闭包工作正确之前,请注意,在循环中重复声明标题变量不起作用(实际上,您可以将变量看作基本上被提升到函数的范围内 – 与其他一些语言不同,用于循环在JavaScript中没有范围,因此该变量仅对该函数声明一次,并且在循环内未声明或重新声明)。在循环之外声明变量应该有助于澄清为什么你的代码不能像你所期望的那样工作。

就是这样,当回调运行时,因为它们在相同的变量i上有一个闭包,所以当我增加时,它们都会受到影响,并且当它们运行时都会使用i的当前值(这将是错误的,因为你发现,因为循环完成创建回调之后运行回调)。异步代码(例如JSON调用响应)在所有同步代码执行完毕之前不会运行,因此在执行任何回调之前,循环将保证完成。

为了解决这个问题,你需要一个具有自己的范围来运行的新函数,以便在循环内声明的回调中,每个不同的值都有一个新的闭包。您可以使用单独的函数执行此操作,也可以在回调参数中使用调用的匿名函数。以下是一个例子:

var title, i;
for (i = 0; i < some_array.length; i += 1) {
    title = some_array[i];
    $.getJSON(
       'some.url/' + title,
       (function(thisi) {
          return function(data) {
             do_something_with_data(data, thisi);
             // Break the closure over `i` via the parameter `thisi`,
             // which will hold the correct value from *invocation* time.
          };
       }(i)) // calling the function with the current value
    );
}

为了清楚起见,我将其分解成一个单独的函数,以便您可以看到发生了什么:

function createCallback(item) {
   return function(data) {
      do_something_with_data(data, item);
      // This reference to the `item` parameter does create a closure on it.
      // However, its scope means that no caller function can change its value.
      // Thus, since we don't change `item` anywhere inside `createCallback`, it
      // will have the value as it was at the time the createCallback function
      // was invoked.
   };
 }

var title, i, l = some_array.length;
for (i = 0; i < l; i += 1) {
    title = some_array[i];
    $.getJSON('some.url/' + title, createCallback(i));
    // Note how this parameter is not a *reference* to the createCallback function, but
    // the *value that createCallback() returns*, which is itself a function.
}

注意:由于你的数组显然只有它的标题,你可以考虑使用标题变量而不是我,这需要你回到some_array。但任何一种方式都可以,你知道你想要什么。

考虑这一点的一个潜在有用的方法是,回调创建函数(无论是匿名的还是createCallback函数)本质上都将i变量的值转换为单独的thisi变量,每次都引入一个具有自己的作用域的新函数。也许可以这样说:“参数将关闭值从断点中分离出来”。

请小心:由于对象是引用类型,因此此技术不会对对象进行复制,因此无法复制。只是传递他们作为参数将不会产生一些事实之后不能改变的东西。您可以复制所有您喜欢的街道地址,但这不会创建一个新房子。如果你想要一个导致不同之处的地址,你必须建造一座新房子。

http://stackoverflow.com/questions/6129145/pass-extra-parameter-to-jquery-getjson-success-callback-function

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:javascript – 将额外的参数传递给jQuery getJSON()成功回调函数