IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Javascript setInterval() problém

V předchozím kvízu, Online test znalostí JavaScript, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
michaelmik
Člen
Avatar
michaelmik:6.1.2019 17:11

Ahoj, potřeboval bych poradit s problémem, který mě již delší dobu trápí.
Mám přes PHP vytvořenou funkci na tlačítka(uvedu zde příklad:)
function neco(id, odkaz)
{
echo "<button id=$id></button>";
echo "
<script>
$("#$id").clic­k(function(){
$("#board").lo­ad($href);
});
</script>
";
}

...když mám tyto funkce vyvolané dvě:
neco(0,"../ne­co/load.php");
neco(1,"../ne­co/load.php");

tak na této stránce load.php mám funkci, ve které mi Javascript spustí setInteval().
Potíž je v tom, že když kliknu na obě tlačítka .. tak stránka load.php se začne "houpat"(začnou se "prát") jako kdyby to vyvolávalo obě funkce, tzn. když mám setInterval(funkce, 1000) v load.php .. tak jednou stránka načte obsah z jedné funkce s ID 0 a za vteřinu to udělá samé s ID 1 .. a takhle se to houpe každou vteřinu.

Dle obrázku jde o to, že když kliknu na prvního uživatele, který má např: id 0, tak do DIVu vedle skočí jeho text.
Ale když dále kliknu na druhého uživatele s id 1, tak najednou to spustí "houpací" proces a už tam napřeskáčku se ukazují ty texty obou uživatelů..

Zkusil jsem: Zkoušel jsem to vyřešit clearInterval() avšak bezúspěšně.

 
Odpovědět
6.1.2019 17:11
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:7.1.2019 9:56

Nerekl jsi, ceho chces docilit.

K zadnemu houpani nedochazi. Nebo, aspon ten termin se k tomu vubec nehodi. Asi ti schazi zakladni znalosti pc.
Takze, v pc existuji procesy, ktere se spousti opakovane, podle planu. Funguje to podobne jako win-naplanovane ulohy.
Mezi temito procesy je napriklad zobrazovani kurzoru mysi nebo zpracovani jinych timer-eventu.
Asi to to ale nedokazi spravne vysvetlit....

Plan je seznam funkci, ktere se maji provest.
Pouzitim setInterval vyvola funkci pridej do planu.
Spravnym pouzitim clearinterval spusti odebrani z planu.
Ajax nastaveny asynchronne se take pridava do tohoto planu.
V pc pak probiha jakesi tikani, ktere se pokusi zavolat vsechno v planu. V tom planu u setInterval mas treba zadane, ze se to spousti jen, kdyz je cas t=xxxxxxx65432. U ajaxu, ze ma zkusit kazdych 100 ms stahnout data.

No, a co se ti tam deje. Asi spatne obsluhujes set a clear a nebo mas maly cas.

Pokud spoustis funkci treba kazdych 100 ms a nemuzes zarucit, ze vykonani te funkce nepresahne 100 ms, dojde k tomu, ze se spousti treba 2x 3x totez a muze si to vzajemne prepisovat data. To zalezi na tom, jak to mas osetrene. V tomto pripade je treba pridat cas nebo pouzit clear a nebo pouzit jino funkci treba setTimeout, ktera se opakovane nespousti.

Mas 2 tlacitka, kazde se pokousi stahovat tutez stranku. To by nevadil, pokud to mas osetrene. Pokud ne, dojde k tomu, ze si kazdy stahne vlastni data a pokusi se je zobrazit. Jenze ty to nemas osetrene, tak si to vzajemne prepisuji. ted je ovsem otazka, co s tim chces provest. Tos nenapsal. Mozna bys mohl udelat vlastni planovaci funkci, kam pridat spusteni ajaxu, pokud uz neni v seznamu jine spusteni. Nebo predchozi spusteni zrusis. A nebo k predchozimu spusteni pridas dalsi data, ktera ma jeste stahnout.

plan = {}
plan.seznam = []
plan.pridej = function()
  {plan.seznam[plan.seznam.length] = data;}
plan.proved = function()
  {
   var i, i_end, data;
   i_end = plan.seznam.length;
   for (i=0; i<i_end;i++) {
      data = plan.seznam[i];
      if (data!=null)
          ajax(data); plan.seznam[i] = null;
      }
   }
setInterval("plan.proved()",1000);
// kdyz je seznam prazdny, sice to bude na pozadi tikat, ale nebude volat ajax
// ano, pouzivam null, nemazu seznam, to si uz vyresis

No, a jestli ti jde o spravne pouziti clear, tak to vypada nejak takto:

timer = null;
timer = setInterval('funkce1()', 1000);
if (timer!=null) clearInterval(timer); // je lepsi se zeptat na null a pouzivat null, protoze jinak pise error do js konzoly, pokud timer neexistuje (ale to by ti treba nevadilo)
timer = setInterval('funkce2()', 1000);
if (timer!=null) clearInterval(timer);
Editováno 7.1.2019 9:57
 
Nahoru Odpovědět
7.1.2019 9:56
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:7.1.2019 10:01

oprava... jeste bych to mozna napsal takto, s tim se da lepe operovat

plan.pridej = function(data)
  {
  var n;
  n = plan.seznam.length;
  plan.seznam[n] = data;}
plan.smaz = function(n)
  {plan.seznam[n] = null;}
plan.ajax = function (data)
  {/*...*/}
plan.proved = function()
  {
   var i, i_end, data;
   i_end = plan.seznam.length;
   for (i=0; i<i_end;i++) {
      data = plan.seznam[i];
      if (data!=null)
          plan.ajax(data);
          plan.smaz(i);
      }
   }
 
Nahoru Odpovědět
7.1.2019 10:01
Avatar
michaelmik
Člen
Avatar
michaelmik:8.1.2019 14:39

ahoj .. chtěl bych docílit toho, že když kliknu na uživatele s ID 0, tak v load.php se vybere z DB všechen text s tímto ID - vše co napsal a poté to zobrazí ...
Když kliknu na uživatele s id: 1 tak se spustí celý proces jen s ID 1 ..

Nyní ve skutečnosti když kliknu na ID:0 tak se provede výběr z DB s id:0 a zobrazí výstup - což je ten text.
když ale kliknu dál na uživatele s id:1 tak se také provede výběr z DB s id: 1 a zobrazí výstup ale běhěm vteřiny se přepne zase do výstupu jako kdybych zmáčkl uživatele s id: 0 .. a takhle se to začne samo přeskakovat .. když vypnu setInterval tak vše funguje .. ale bohužel už se mi texty potom neobnovujou ..
Základní znalosti mi neschází .. jen toho kodu mám v podstatě hodně, tudíž proto sem píšu, jestli tam není jen triviální chyba :). Díky za radu a přeji hezký den

 
Nahoru Odpovědět
8.1.2019 14:39
Avatar
michaelmik
Člen
Avatar
michaelmik:8.1.2019 14:41

a bohužel s AJAXEM si už nevím rady. Ten nemohu prostě pochopit jak funguje takže zkouším cestu přes klasický Javascript nebo JQUERY.

 
Nahoru Odpovědět
8.1.2019 14:41
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:9.1.2019 16:04

Njn, takze takze zpet k zakladum, ktere znas :)

setInterval - spousti sekvenci prikazu opakovane, treba kazdou 1s sekundu
setTimeout - spousti sekvenci prikazu 1x po uplynuti casu, treba 1s sekundu
Proste, pouzivas spatnou funkci.

(nejsem moc dobry de vysvetlovani)
Ajax ma 2 moznosti. Bud je synchronni nebo asynchronni. Bud se ceka na dokonceni a nebo se spusti jako serie prikazu na pozadi. Obvykle se pouziva asyn.
Pr. Asyn: Mas na strance 5 obrazku a zacnou se vsechny nacitat.
Pr. Syn: Mas na strance 5 obrazku a nejdriv se nacte jeden, pak druhy, ... - Uzivatel hrozne dlouho ceka na obsah, protoze se vis pouziva asyn reseni. Kdyz treba prvni obrazek tahas z pomaleho serveru nekde z webu, tak ceka uzivatel, ceka, uz i repu zasadil...
V kodu to pak vypada takto:

funkce1();
ajax2(url, funkce3);
funkce4();
// asyn: 1, 2, 4 ... 3 - poradi, v jakem se provedou funkce (vyjimecne 1, 2, 3, 4)
// syn: 1, 2 ... 3, 4

Pokud chces tedy po stazeni obsahu provest nejake funkce, musis je napsat do funkce 3. Zanorujes vlastne funkce do funkce. takove volani se nazyva callback

function mojecallbackFunkce(data) {alert(data);} // nebo
// var mojecallbackFunkce = function(data) {alert(data);}

ajax(url, mojecallbackFunkce); // nebo
ajax(url, widow['mojecallbackFunkce']); // vsechny funkce na hlavni urovni mas ulozene v objektu window; da se pouzit treba: window['alert'](data)

Tam proste jako jedna z promennych je pointer na funkci

No, a uplnejsi definice vetsiny ajaxovych funkci ma jeste vic parametru

ajax(url, fnSuccess, fnError, fnTransfer) // kdyz treba stahujes velky soubor, tak pomoci fnTransfer muzes zobrazovat prubeh stahovani
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
9.1.2019 16:04
Avatar

Člen
Avatar
Odpovídá na Peter Mlich
:9.1.2019 17:33

Toto sú hlavne naprosto zbytočné rady - to, čo chce dosiahnuť, je proste nad jeho sily so stávajúcou úrovňou znalostí. Po správnosti si to má proste doštudovať.

Celý ten spôsob ako to realizuje je koncepčné zlý. A ty to ešte zabíjaš navrhnovaním riešenia, ktoré je napohľad tiež zlé. Keby si aspoň navrhol setTimeout, rekurzívne spúšťaný sekundu po vrátení odpovede zo servera, ale setinterval?

Bohužiaľ, toto je celé zle. Ako otázka na ktorú nie je rozumnejšie riešenie od pokračovania v učení sa, tak tá snaha pomôcť, avšak veľmi nevhodným spôsobom.

 
Nahoru Odpovědět
9.1.2019 17:33
Avatar
michaelmik
Člen
Avatar
michaelmik:9.1.2019 21:22

Takže jsem nakonec použil AJAXe pro komunikaci se serverem, kdy vrácené hodnoty jsem použil v setIntervalu, kdy po kliknutí na další tlačítko jsem celý setInterval zrušil a kod se spustil nanovo a tato metoda mi funguje :).
v JQUERY jsem začátečník, proto jsem se zeptal ZDE. Učíme se stále pořád něco nového :). Každopádně děkuji za pomoc.

 
Nahoru Odpovědět
9.1.2019 21:22
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na
Peter Mlich:10.1.2019 7:44

'Keby si aspoň navrhol setTimeout'
Ano, ano, kdyby... Hned v prvni odpovedi. V te posledni jsem to zopakoval. Spis, kdyby ho pouzil, ze? :) Nebo aspon si k tomu vygoogloval nejake priklady. Ono se to i dost spatne vysvetluje, pokud pri programovani vynechal ucitel casovace a jak to funguje, kdyz se stahuje vice souboru najednou a proc se to tak vubec dela.
No, mas otevreny prostor pridat take svuj komentar :)

 
Nahoru Odpovědět
10.1.2019 7:44
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:10.1.2019 20:51

Mne napada jeste, jestli ti jde o tohle, mozna by slo nechat setinterval bezet a jen zmenit url. Zjistit, ze timer_id!=null, tak jen zmenit url. A pri dalsim intervalu uz pouzije novou url.
Ale nevim presne, jakym zpusobem ma tva aplikace pracovat. Mozna by bylo nejlepsi to setTimeout a mozna jinak.

 
Nahoru Odpovědět
10.1.2019 20:51
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.