2013-04-11 81 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); 
     }; 
    })()); 
}