При использовании обратных вызовов внутри цикла в javascript существует ли способ сохранить переменную, которая обновляется в цикле для использования в обратном вызове?
Скажем, у меня есть что-то следующее:
for(var i = 0; i < length; i++){
var variable = variables[i];
otherVariable.doSomething(variable, function(err){ //callback for when doSomething ends
do something else with variable;
}
К моменту вызова обратных вызовов variable
неизбежно будет последней переменной для всех обратных вызовов, вместо того, чтобы быть другим для каждого обратного вызова, как я бы хотел. Я понимаю, что я мог передать variable
в doSomething()
, а затем передать это как часть обратного вызова, но doSomething()
является частью внешней библиотеки, и я бы предпочел не вмешиваться в исходный код для этого.
У вас есть те, кто знает JavaScript лучше, чем я знаю, есть ли альтернативные способы делать то, что я хотел бы сделать?
Лучший, и спасибо,
Сами
Ответы
Ответ 1
Общим, если не уродливым, способом справиться с этой ситуацией является использование другой функции, которая немедленно вызывается, чтобы создать область для хранения переменной.
for(var i = 0; i < length; i++) {
var variable = variables[i];
otherVariable.doSomething(function(v) { return function(err) { /* something with v */ }; }(variable));
}
Обратите внимание, что внутри непосредственно вызываемой функции обратный вызов, который создается и возвращается, ссылается на параметр на функцию v
, а не на внешний variable
. Чтобы сделать это намного лучше, я бы предложил извлечь конструктор обратного вызова как именованную функцию.
function callbackFor(v) {
return function(err) { /* something with v */ };
}
for(var i = 0; i < length; i++) {
var variable = variables[i];
otherVariable.doSomething(callbackFor(variable));
}
Ответ 2
Хорошо, мне показалось, что это понятно. Мне нужно было сделать обертку function(var)
вокруг otherVariable.doSomething()
, поэтому обновленный код выглядит следующим образом:
for(var i = 0; i < length; i++){
var variable = variables[i];
(function(var){ //start wrapper code
otherVariable.doSomething(var, function(err){ //callback for when doSomething ends
do something else with var; //please note that i'm dealing with var here, not variable
}
})(variable);//passing in variable to var here
}
надеюсь, что это поможет кому-то еще, кто застрянет в этом, в будущем!
@aparker42, я все равно хотел бы услышать ваш ответ на мой вопрос в комментарии к вашему вопросу, так как это все еще меня путает.
EDIT: конечно, поскольку это javascript, вы не хотели бы использовать var
в качестве имени переменной.