2013-04-11 3 views
1

У меня есть этот пример кода:Как передать переменную в функцию обратного вызова getJSON на успех

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

Однако переменная я в функции обратного вызова не соответствует тому, что можно было бы ожидать. Цикл 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 и нажмите Run, наблюдая выход консоли s.

Код от 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); 
     }; 
    })()); 
} 
Смежные вопросы