MC, 18:48 poniedziałek, 30.04.2012 r.
Ilustracja do artykułu: Javascript - setTimeout() i wywoływanie funkcji z argumentami

Javascript - setTimeout() i wywoływanie funkcji z argumentami

Zdarzenia w Javascript oparte na czasie, czyli generalnie użycie funkcji setTimeout(), czy clearTimeout(), od zawsze było moją zmorą. Jak tylko przychodziło mi jej użyć, to wiedziałem, że będzie problem. Teraz, kiedy mam już opracowane pewne metody działań sprawa ze zdarzeniami czasowymi nie jest już tak problematyczna. W tym wpisie zanotuję dla siebie jak i możliwe, że innych, sposób na poprawne wywoływanie funkcji z argumentami i bez nich, za pomocą setTimeout().

W czym właściwie problem?

Problem generalnie rozbija się o to, że w ogromnej większości przykładów na użycie funkcji setTimeout(), jakie możemy znaleźć w sieci, przekazuje nazwę funkcji do wykonania jako stringa, np.
setTimeout("FunkcjaDoWykonania()", 2 * 1000);
Rzecz w tym, że jest to podejście zupełnie nieprzydatne w momencie, w którym nasza FunkcjaDoWykonania, miałaby przyjąć jakieś argumenty, ponieważ analogiczne wywołanie:
setTimeout("FunkcjaDoWykonania(parametr1, paramatr2)", 2 * 1000);
nie zadziała. Ba! Przyznam się szczerze, że jak tylko ja się zabiorę za Javascript, to bardzo często i pierwsze podejście mi nie działa ;) Dlatego też takiego podejścia unikam jak ognia a w zamian proponuję inne.

Mniej fajne podejście

Najpierw chciałbym pokazać mniej elegancki ze sposobów, ale za to skuteczny. To tak, by uniknąć przesyłania wywołania funkcji jako stringa, które jak już wspomniałem, zdarza mi się wyłączyć z działania. Zamiast stringa proponuję funkcję przypisać zmiennej i to ją wysłać do funkcji setTimeout(). Spójrzmy na poniższy przykład:
var wyswietlKomunikat = function()
{
alert("Komunikat");
setTimeout(wyswietlKomunikat, 2 * 1000);
}
setTimeout(wyswietlKomunikat, 2 * 1000);
Jak widzimy stworzyliśmy zmienną wyswietlKomunikat, która de facto jest wskaźnikiem na funkcję i możemy ją przekazać do setTimeout(). Powyższy skrypt nie robiłby nic innego, jak wyświetlanie co 2 sekundy bezużytecznego komunikatu, ale myślę, że jako przykład jest całkiem klarowny.

To teraz do sedna...

Dobrze, czas na najwłaściwszy moim zdaniem ze sposobów, który pozwoli zarówno pominąć przesyłania funkcji jako stringa, jak i przekazać do funkcji dowolną liczbę parametrów/argumentów! Wszystko tak naprawdę sprowadzi się do nieco innego wywołania funkcji setTimeout(). Spójrzmy na poniższy przykład, który wszystko wyjaśni.
function DoWykonania(parametr1, parametr2)
{
var suma = parametr1 + parametr2;
alert(parametr1 + " + " +parametr2 + " = " + suma);
setTimeout(function(){DoWykonania(suma, parametr1)}, 3 * 1000);
}

setTimeout(function(){DoWykonania(1, 2)}, 3 * 1000);
Powyższy skrypt będzie wyświetlał co 3 sekundy komunikat z wynikiem sumowania dwóch liczb, które kolejno będą się zmieniały. Jednak najistotniejsza jest składnia wywołania funkcji setTimeout, setTimeout(function(){DoWykonania(1, 2)}, 3 * 1000), w którym właściwie obudowujemy wywołanie funkcji DoWykonania() w inną funkcję przekazywaną do setTimeout(). Takie podejście zadziała na pewno.

Nasz przykład jest niezwykle prosty, zatem nie ujawnił się tutaj pewien mankament tego wywołania. Gdy przekazujemy do funkcji bardziej złożone parametry to należało by uniknąć ewentualnych wycieków pamięci, dlatego poprawne wywołanie z przesłaniem jakichś obiektów powinno wyglądać:

setTimeout(function(){DoWykonania(obiekt1, obiekt2); obiekt1 = null; obiekt2 = null;}, 3 * 1000);
Czyli przypisze ono nulle przesyłanym obiektom, gdy będzie już po sprawie.

Czy to wszystko?

To właściwie tyle. Z doświadczenia wiem, że wiedza ta potrafi ustrzec najbliższe otoczenie od wysłuchiwania okrutnych przekleństw ;)

Komentarze (0) - Nikt jeszcze nie komentował - bądź pierwszy!

Imię:
Treść: