SetInterval a vlastní proměnná – JavaScript, AJAX, jQuery – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

SetInterval a vlastní proměnná – JavaScript, AJAX, jQuery – Fórum – Programujte.comSetInterval a vlastní proměnná – JavaScript, AJAX, jQuery – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Figa0
Super člen
25. 11. 2010   #1
-
0
-

Ahoj mám tento kod:



counter = 1;
updates[counter] = window.setInterval('update(1, counter)', 10000);
counter++;
updates[counter] = window.setInterval('update(1, counter)', 10000);

A potřebuji aby se kadé opakování fce volalo s tím původním couterem a ne jako teď že i první opakování je voláno s counter = 2 Předem děkuji za odpovědi.

Nahlásit jako SPAM
IP: 90.177.38.–
Reklama
Reklama
pepiino0
Duch
26. 11. 2010   #2
-
0
-

To Figa :
Stačí použít správně closure:



function makeIntervalHandler(counter) {
return function() {
update(1,counter);
}
}

var counter = 1;
updates[counter] = window.setInterval(makeIntervalHandler(counter), 10000);
counter++;
updates[counter] = window.setInterval(makeIntervalHandler(counter), 10000);

Nahlásit jako SPAM
IP: 84.42.216.–
Josef Adamčík [br] email: josef.adamcik@gmail.com [br] blog: http://zapisnik.pepiino.cz [br] ( O JavaScriptu, webu a vůbec...) twitter: http://twitter.com/pepiino [br] homepage: http://josef-adamcik.cz [br]
Figa0
Super člen
26. 11. 2010   #3
-
0
-

Děkuji funguje to. Mohu poprosit o jednoduché vysvětlení?

Nahlásit jako SPAM
IP: 90.177.38.–
pepiino0
Duch
28. 11. 2010   #4
-
0
-

Pokusím se to vysvětlit jednoduše.

Nejdřív kde je problém v původním kódu:



updates[counter] = window.setInterval('update(1, counter)', 10000);


Zde předáváš do setInerval řetězec s JS kódem. To znamená, že ve chvíli spuštění události (cca každých 10000ms) se vlastně provedel eval (což je mimochodem důvod, proč je předávání řetězců do setInerva a setTimeout považováno za nedobré). Ve chvíli vyhodnocení kódu je potřeba proměnná counter, ta je nalezena v globálním oboru platnosti. V tu chvíli je v ní ale již hodnota 2.

Řešení využívá lexikálního uzávěru (neboli closure). Princip: v každé funkci máš přístup k lokálním proměnným deklarovaným pomocí klíčového slova var (viz http://zapisnik.pepiino.cz/co-byste-meli-vedet-o-javascriptu-1-promenna-a-globalni-obor-platnosti/), jejím parametrům (a pak this, arguments ..., to nás ale teď nezajímá) a navíc k lokálně dostupným proměnným funkce, v jejížm těle byla deklarována. Tento princip se řetězí (tedy "lokálně dostupné proměnné funkce v níž byla deklarována" jsou vybrány podle stejného principu). Pokud je funkce deklarována na globální úrovni, má přístup alespoň ke globálnímu scope. Samozřejmě platí, že parametry a lokální proměnné překrývají stejně pojmenované proměnné z venčí (tedy z lexikálního uzávěru).

Teď už můžeme dát dohromady, proč tento kód funguje:


function makeIntervalHandler(counter) {
return function() {
update(1,counter);
}
}

makeIntervalHandler vrací při zavolání funkci. Funkce je deklarována v jejím těle, takže má přístup i k jejímu parametru counter. A to i dávno po té, co je vrácena. Parametr counter překryje glonální proměnnou counter a číslo se v JS předá hodnotou, takže proměnná neodkazuje na stejnou hodnotu, jako globální counter. V closure se tak uchová hodnota z doby, kdy byla makeIntervalHandler zavolána.



updates[counter] = window.setInterval(makeIntervalHandler(counter), 10000);

Tady si zavolání makeIntervalHandler vyrobím funkci pro setInterval. Vrácená funkce bude volána až po uplynutí 10000ms, ale hodnotu předanou přes counter mám díky closure zafixovanou.


Asi to není tak jednoduché, jak bych chtěl. Ale scope v JavaScriptu a closure chtějí trochu času na pochopení. Pokud není něco jasné, klidně se zeptej.





Nahlásit jako SPAM
IP: 84.42.216.–
Josef Adamčík [br] email: josef.adamcik@gmail.com [br] blog: http://zapisnik.pepiino.cz [br] ( O JavaScriptu, webu a vůbec...) twitter: http://twitter.com/pepiino [br] homepage: http://josef-adamcik.cz [br]
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 36 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý