2011-08-13 6 views
53

Powiedzmy mam coś w następujący sposób:Podczas korzystania z wywołań zwrotnych w pętli javascript, czy istnieje sposób na zapisanie zmiennej, która została zaktualizowana w pętli do wykorzystania w wywołaniu zwrotnym?

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; 
    } 

Do czasu wywołania zwrotne są nazywane, variable nieuchronnie być ostatnia zmienna dla wszystkich wywołań zwrotnych, zamiast być inna dla każdego wywołania zwrotnego, jak bym lubić. Zdaję sobie sprawę, że mógłbym przekazać variable do doSomething(), a następnie odebrać go jako część wywołania zwrotnego, ale doSomething() jest częścią zewnętrznej biblioteki, a ja wolałbym nie ingerować w kod źródłowy.

Czy tych z Was, którzy znają JavaScript lepiej niż ja wiem, czy istnieją jakieś alternatywne sposoby, aby robić to, co ja lubię robić?

najlepsze, a dzięki,
Sami

Odpowiedz

41

Powszechnym, czy brzydki, sposób radzenia sobie z tej sytuacji jest użycie innej funkcji, która jest natychmiast wykonywany w celu stworzenia możliwości, aby utrzymać zmienną.

for(var i = 0; i < length; i++) { 
    var variable = variables[i]; 
    otherVariable.doSomething(function(v) { return function(err) { /* something with v */ }; }(variable)); 
} 

Zauważ, że wewnątrz natychmiast wywołał funkcję wywołania zwrotnego, który jest tworzony i wrócił, odwołuje parametr do funkcji v a nie poza variable. Aby uczynić ten odczyt znacznie lepszym, sugerowałbym wyodrębnienie konstruktora wywołania zwrotnego jako nazwanej funkcji.

function callbackFor(v) { 
    return function(err) { /* something with v */ }; 
} 
for(var i = 0; i < length; i++) { 
    var variable = variables[i]; 
    otherVariable.doSomething(callbackFor(variable)); 
} 
+0

Niestety, to nie pomoże w moim przypadku, ponieważ doSomething() jest funkcją z biblioteki, której nie chcę edytować. Gdy ta biblioteka zostanie zaktualizowana, będę musiał ponownie edytować kod źródłowy i jest to coś, z czym po prostu nie chcę się zajmować. Zakładając, że nie mogę zmienić funkcji doSomething(), czy jest coś co mogę zrobić? – thisissami

+0

Nie wymaga to żadnych zmian w 'doSomething()'. Zakładam, że 'doSomething' po prostu odebrał wywołanie zwrotne i że włączenie parametru' variable' było czymś, co być może chciałbyś zmienić. Jeśli podpis 'doSomething' to' doSomething (val, callback) 'to po prostu zmodyfikuj mój przykład do' otherVariable.doSomething (variable, callbackFor (variable)) '. Ważne jest to, że tworzony jest nowy zakres, poprzez wywołanie funkcji, aby utrzymać wartość zmiennej dla funkcji wywołania zwrotnego. – aparker42

+0

Hmm, więc myślę, że jestem nieco zdezorientowany. Sposób działania 'doSomething()' polega na tym, że przekazał on zmienną, a ostatecznie 'doSomething()' wywoła określoną funkcję zwrotną, gdzie pierwszym parametrem jest dowolny kod błędu, który wynikał z 'doSomething()'. Jeśli wstawię wrapper funkcji (zmiennej) wokół wywołania zwrotnego, aby utworzyć nowy zakres, czy to nie funkcja 'function (variable)' stanie się callback zamiast, a parametr 'variable' faktycznie będzie komunikatem o błędzie? – thisissami

31

Ok mam wydawało dowiedzieć się tego. Co muszę zrobić żeby umieścić function(var) owijkę wokół otherVariable.doSomething(), więc zaktualizowany kod wygląda następująco:

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 
} 

nadzieję, że to pomoże ktoś inny, że utknie na coś takiego w przyszłości!

@ aparker42, ja wciąż kocham usłyszeć odpowiedź na moje pytanie w komentarzu do Twojego pytania, ponieważ nadal nie mylić mnie.

EDIT: oczywiście, ponieważ jest to JavaScript, nie chcesz używać var jako nazwy zmiennej.

+3

Tak, to w gruncie rzeczy to samo, co moja odpowiedź.Różnica polega na tym, że używasz funkcji bezpośrednio wywoływanej, aby utworzyć zakres, w którym wykonasz wywołanie polecenia 'doSomething'. Moja odpowiedź właśnie stworzyła wywołanie zwrotne w tym zakresie, a następnie zwróciła je. W końcu obaj osiągają to samo. – aparker42

+0

Aby wesprzeć i wyjaśnić, tak, jest to ta sama odpowiedź, którą aparker42 podał właśnie w innym formacie. Oddzwanianie w tym przypadku nie jest WYWOŁANE przez Zrób coś, natychmiast zwraca wartość. – dudewad

+14

Być może nie jest to taki dobry pomysł, aby mieć identyfikator o nazwie 'var' w JavaScript. – danijar

Powiązane problemy