Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: clearTimeout w klasie nie przestaje wywoływać metody
Forum PHP.pl > Forum > Po stronie przeglądarki > JavaScript
starach
Napisałem sobie klasę Counter która ma służyć za prosty licznik który wykorzystam przy wywołaniach AJAX'a.
Niestety z jakiegoś niewiadomego mi powodu wewnętrzna metoda sprawdzająca nie wyłącza mi licznika. Z zewnątrz mogę to zrobić, ale z wew. klasy nie.

Kod
function Counter()
{
    this.jump = 1;
    this.meter = 0;
    this.timeout = 100;
    this.count_to = null;
    this.evt_func = null;
    this.task_pointer = null;
    var ths = this
    
    this.start = function()
    {
        this.meter += this.jump;
        if(this.evt_func !== null)
        {
            setTimeout(this.evt_func, 0);
        }
        if(this.count_to !== null && this.count_to == this.meter)
        {
            this.stop();
        }
        this.task_pointer = setTimeout(function(){ ths.start(); }, this.timeout);
    }
    this.stop = function()
    {
        $('span#test2').html(this.meter);
        clearTimeout(this.task_pointer);
    }
    this.eventRegister = function($fn)
    {
        if(!jQuery.isFunction($fn)) {
            alert('Paremeter incorrect given for Counter::eventRegister');
        } else {
            this.evt_func = $fn;
        }
    }
}

$Counter = new Counter();
$Counter.meter = 0;
$Counter.count_to = 20;
$Counter.eventRegister(function($Counter)
{
    $('span#test').html($Counter.meter);
});
$Counter.start();

$Counter.meter może nie działać bo kod przepisałem z mojej klasy obsługi wywołania AJAX która jest statyczna zmieniając function() na function($Counter) więc nie jestem pewien czy ten przykład będzie śmigać tak jak powinien. Ale u mnie $('span#test') zmienia swoją wartość co sekundę. Natomiast $('span#test2') gdy licznik dojdzie do 20. Niestety nie zatrzymuje się na nich tylko jedzie dalej do usranej śmierci... Z kolei jeśli wywołam metodę stop z zewnątrz klasy to licznik przestaje dalej lecieć. Co może być przyczyną?

p.s.
Tak przy okazji się zapytam. Wiecie może jak wywołanie 'zdarzenia licznika' setTimeout(this.evt_func, 0); zastąpić czym nie wykorzystującym setTimeout? Chodzi mi o to jak mam to w inny sposób wywołać.
erix
Cytat
Tak przy okazji się zapytam. Wiecie może jak wywołanie 'zdarzenia licznika' setTimeout(this.evt_func, 0); zastąpić czym nie wykorzystującym setTimeout? Chodzi mi o to jak mam to w inny sposób wywołać.

A zwykłe this.evt_func() nie działa?

Cytat
Niestety nie zatrzymuje się na nich tylko jedzie dalej do usranej śmierci... Z kolei jeśli wywołam metodę stop z zewnątrz klasy to licznik przestaje dalej lecieć. Co może być przyczyną?

Konsola JavaScript coś mówi?
starach
Cytat(erix @ 6.04.2009, 17:10:37 ) *
A zwykłe this.evt_func() nie działa?
Dzięki. Oczywiście rzecz najoczywistsza i o niej nie pomyślałem.
Cytat(erix @ 6.04.2009, 17:10:37 ) *
Konsola JavaScript coś mówi?
No niestety właśnie nic. Konsola błędów firefoksa czysta, konsola firebug'a czysta. sad.gif
erix
Masz możliwość wypuszczenia tego skryptu w działaniu? Chociaż JS ze strukturą HTML, w ciemno trochę ciężko modzić.
lord_t
To się nie zatrzymuje ponieważ chcesz zastopować timeouta który już minął, tego poprzedniego.

Daj to:
Kod
this.task_pointer = setTimeout(function(){ ths.start(); }, this.timeout);

Przed ifa który ma stopować.

Proponowałbym przejść na setInterval() albo nie tyle stopować timeout co w ogóle go nie uruchamiać:

Coś takiego (bardziej luźna myśl jak kod z prawdziwego zdarzenia):
Kod
if(this.count_to !== null && this.count_to == this.meter)
{}
else
setTimeout(function(){ ths.start(); }, this.timeout);
starach
Zaraz wypróbuje twój kod lord_t.

Reprodukcja błędu: http://www.orglee.com/testy/licznik/

Dałem "this.task_pointer = setTimeout(function(){ ths.start(); }, this.timeout);" w else i zaczęło działać.

Jak on cholera ten skrypt wykonuje?!?!
lord_t
Rozwiń swoje pytanie;) Bo wykonuje jak zaimplementowałeśbiggrin.gif
erix
AFAIR w callbackach nie powinno się używać this.
lord_t
Ale to nie bezpośrednio this.
erix
Ale callback jest wywoływany anonimowo, to co jest kontekstem dla tej funkcji? tongue.gif Trzeba by było podstawić jakąś instancję, to wtedy rozumiem. Ale póki co - w wywołaniu jej nie ma.

A tak BTW, ~orglee, masz literówkę; ths zamiast this.
starach
No właśnie nie erix. To nie jest literówka. Wcześniej deklaruję var ths = this inaczej odwołanie by nie działało zmienne klasowe nie sięgają do funkcji wew. czy jak to inaczej nazwać. Natomiast tak zadeklarowana referencja do obiektu zadziała.

Chodziło mi o to dlaczego on zamiast wykonać najpierw stop() wywołuje setTimeout(). Dla mnie to jest cholera nielogiczne.
lord_t
erix:no jest wywoływany anonimowo, ale podajesz mu gotowy obiekt-funkcję(anonimową instancję) gdzie w chwili stworzenia jest znana wartość/adres ths.

orglee, to jest logiczne: najpierw działa stop, ale w chwili kiedy działa w task_pointer jest timeout ten który się wykonał. Po tym zastopowaniu tego co się juz zrobiło wpisujesz nowy timeout do task_pointer, a tego już poprzednim stopem nie zatrzymasz.
erix
Fakt, przeoczyłem ths.
starach
A ja przeoczyłem fakt że tępak ze mnie...

No oczywiście że to jest logiczne. Dziękuję bardzo pewnie gdybym sam szukał przyczyny nie znalazłbym prędko... :|

edit>
Dałem 3 razy pomógł mam nadzieję że nie przesadziłem.

Jeszcze jakbyście mi powiedzieli dlaczego należy używać setInterval zamiast setTimeout.

edit>>
Ok już znalazłem.
Cytat
What is setTimeout():

It is a function that can execute other javascript statement AFTER x interval. The interval unit is millisecond.

Syntax:

setTimeout(”do.something();”, 1000); //Execute do.something() 1 second later.

What is setInterval():

It is a function that can execute other javascript statement EVERY x interval. The interval unit is millisecond.

Syntax:

setInterval(”do.somethingElse();”, 2000); //Execute do.somethingElse() every 2 seconds.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.