2013-04-11 79 views
1

我有这样的例子代码:如何将变量传递给的getJSON回调函数成功

for (var i = 0; i < array.length; i++) { 
    $.getJSON("http://someapi", { "one": two }, function (result) { 
     array[i].value = result.value; 
    }); 
} 

但是在回调函数的变量i不对应的是人们可以期待。 for循环运行速度非常快,并在第一个回调函数接收到答案之前完成,因此i变量位于循环中的某个位置,甚至完成并超出了数组边界。

无论如何,有没有办法将一个变量传递给回调函数?事情是这样的:

$.getJSON("http://someapi", { "one": two }, function (result, i) { 
    array[i].value = result.value; 
}); 

回答

4
for (var i = 0; i < array.length; i++) { 
    $.getJSON("http://someapi", { "one": two }, (function(j) { 
     return function (result) { 
      array[j].value = result.value; 
     }; 
    })(i)); // Immediate invocation is your best friend 
} 

就像当你声明的回调(而不是当它像评估在你的代码),您可以通过i变量。

3

创建附加的封闭存储当前指数和使用您的实际函数内部应该做的伎俩,与此类似:

for (var i = 0; i < array.length; i++) { 
    $.getJSON("http://someapi", { 
     "one": two 
    }, (function() { // added closure... 
     var currentIndex = i; //...to allow declaration of additinal variables 

     return function (result) { 
      array[currentIndex].value = result.value; // use currentIndex here 
     }; 
    })()); //() force immidiate execution 
} 

DEMO - 不使用关闭和使用之间的结果比较封闭


打开DEMO,然后单击运行,看控制台输出秒。从DEMO

代码:

var array = [1, 2, 3, 4, 5]; 

// Wihtout closure i is not always as expected. 
for (var i = 0; i < array.length; i++) { 
    $.getJSON("#", { 
     "one": 1 
    }, function (result) { 
     console.log('no-closure: ' + i); 
    }); 
} 

// With closure stored i (currenIndex) is in the expected order 
for (var i = 0; i < array.length; i++) { 
    $.getJSON("#", { 
     "one": 1 
    }, (function() { 
     var currentIndex = i; 
     return function (result) { 
      console.log('closure: ' + currentIndex); 
     }; 
    })()); 
} 
相关问题