Automatyczna aktualizacja wyświetlanych wartości

0

Posiadam urządzenie mierzące temperaturę, ciśnienie i wilgotność. Poniżej zamieszczam kod java wbudowany w stronę, który pobiera dane z urządzenia i na podstawie trzech funkcji wyświetla wartości. Zmieniają się one dynamicznie. Na podstawie temperatury i ciśnienia muszę wyznaczyć punkt rosy. Jego wyznaczeniem zajmuje się funkcja dewPoint. Na chwile obecną funkcja działa po kliknięciu na button przelicz. Czy jest możliwość aby funkcja uruchamiała się co jakiś zdefiniowany czas i sama uaktualniała wyświetlaną wartość?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script language="JavaScript" type="text/javascript">
		<!--
			var a=0;
			var b=0;
			function Temp (iVal, iSensor)
 			{
			a = document.getElementById('temp').firstChild.data = iVal;
			}
			function Humidity (iVal, iSensor)
 			{
			b = document.getElementById('hum').firstChild.data = iVal;
			}
			function Pressure (iVal, iSensor)
 			{
			document.getElementById('pres').firstChild.data = iVal;
			}
			function sensorChanged( iDevice, iSensor, iVal )
			{
			if (iSensor==0){Temp (iVal)};
			if (iSensor==1){Humidity (iVal)};
			if (iSensor==2){Pressure (iVal)};
			}
			function dewPoint ()
			{
			var c;
			c = document.getElementById('dew').firstChild.data = Math.sqrt(Math.sqrt(Math.sqrt(b/100)))*(112+(0.9*a))+(0.1*a)-112;
			}
						-->
		</script>

</head>
<body style="background-color: #79ACDF;
font-family: Arial, Helvetica, sans-serif;">
<div align="center"><noscript> JavaScript is not activated
or not supported </noscript>
<p><applet name="Analog" archive="A.jar" code="A.class"
codebase="http://192.168.1.230" height="0" width="0" mayscript>

<param name="device" value="0">
<param name="showerrors" value="on">
<param name="sensorpolling" value="on">
<param name="pollingrate" value="4000">
Java is not activated or is not supported
</applet></p>
<table width="200" cellspacing="0" cellpadding="0" bordercolor="#FFFFFF"
align="center">
<tr bgcolor="#CCCCCC">
<td id="temp" align="center">0<font> °C</font></td>
</tr>
<tr bgcolor="#999999">
<td>
<div align="center"><font size="2" color="#FFFFFF">Temperatura</font></div>
</td>
</tr>
<tr bgcolor="#CCCCCC">
<td id="hum" align="center">0<font> %rel.</font></td>
</tr>
<tr bgcolor="#999999">
<td>
<div align="center"><font size="2" color="#FFFFFF">Wilgotność</font></div>
</td>
</tr>
<tr bgcolor="#CCCCCC">
<td id="pres" align="center">0<font> hPa</font></td>
</tr>
<tr bgcolor="#999999">
<td>
<div align="center"><font size="2" color="#FFFFFF">Ciśnienie</font></div>
</td>
</tr>
<tr bgcolor="#CCCCCC">
<td id="dew" align="center">0<font> °C</font></td>
</tr>
<tr bgcolor="#999999">
<td>
<div align="center"><font size="2" color="#FFFFFF">Punkt rosy</font></div>
</td>
</tr>
<tr><td align="center">
<form>
<input type ="button" align="center" value="Przelicz" onClick="dewPoint ()">
</form>
</td>
</tr>
</table>
</div>
</body>
</html>
0

Jscript to nie Java... zły dział.

0

@keraj:
Tak naprawdę to gościu używa Javy, zauważ proszę element applet. Sam JavaScript w zwykłej przeglądarce nie jest w stanie współpracować z urządzeniem zewnętrznym. Tym zajmuje się zapewne applet Javy, wywołując co jakiś czas funkcję JavaScriptową sensorChanged -- przynajmniej tak podejrzewam, bo nie mam pojęcia, co ten Applet robi.

@scorpio:
Jasne, że się da odpalać funkcję co jakiś czas. JavaScript ma do tego wbudowaną funkcję setInterval. Należy jej przekazać dwa argumenty: funkcję, która ma być wywoływana i czas, który ma dzielić kolejne wywołania (w milisekundach).

Przykładowo, jeśli chcesz wywoływać dewPoint co dwie sekundy (czyli 2000 milisekund), użyj:

setInterval(dewPoint, 2000);

Funkcja będzie wywoływana co 2 sekundy i tak w koło Macieju, aż do zamknięcia okna/karty przeglądarki. Jeśli chcesz w którymś momencie przerwać wywoływanie funkcji, możesz użyć funkcji clearInterval. setInterval zwraca pewną wartość identyfikującą okresowe wywoływanie danej funkcji. Jeśli przekażesz tę wartość clearInterval, to zastopuje to okresowe wywoływanie Twojej funkcji.

Najprościej to ogarnąć na przykładzie:


// zapamietujemy identyfikator w zmiennej intervalId
var intervalId = setInterval(dewPoint, 2000);

// ...

// ok, juz nie chcemy okresowego wywolywania dewPoint
clearInterval(intervalId);

Wracając do Twojego początkowego problemu: nie mam pojęcia, czy samo wywoływanie dewPoint wystarczy, tj. czy applet będzie aktualizował poprawnie zmienne a i b. Musiałby odpowiednio często wywoływać Twoją funkcję sensorChanged.

0

Funkcja będzie wywoływana co 2 sekundy

Pod warunkiem że wstawisz setInterval() w funkcję, a nie obok niej.

Tutaj masz cały kod:

var c;
function dewPoint () {
c = document.getElementById('dew').firstChild.data = Math.sqrt(Math.sqrt(Math.sqrt(b/100)))*(112+(0.9*a))+(0.1*a)-112;
setInterval('dewPoint()', 2000);
}
dewPoint();
0

@Demonical Monk:
"Pod warunkiem że wstawisz setInterval() w funkcję, a nie obok niej."
Stwierdzenie to jest nieprawdą, a podany przez Ciebie kod jest niebezpieczny.

Wygląda na to, że pomyliłeś setInterval z setTimeout. Jeśli użyłbyś setTimeout, Twój kod byłby OK -- setTimeout(f, n) wywołuje (raz) funkcję f po około n milisekundach. Dlatego Twój kod powodowałby, że funkcja f będzie wielokrotnie wywoływana, a poszczególne wywołania będzie dzielić (około) n milisekund.

Jednak użyłeś funkcji setInterval(f, n). Wywołanie tej funkcji (pojedyncze wywołanie) powoduje, że funkcja f będzie wywoływana wielokrotnie w odstępach (około) n-milisekundowych. Załóżmy, że wywołasz setInterval(f, 1000) raz. Za około sekundę wywołana zostanie funkcja f. W kodzie, jaki zaprezentowałeś, wewnątrz funkcji f wywołujesz znowu setInterval(f, 1000). Dlatego po kolejnej mniej-więcej sekundzie, funkcja f zostanie wywołana raz (dzięki pierwszemu setInterval) i po chwili drugi raz (dzięki drugiemu). Po kolejnej sekundzie f zostanie wywołana 3x i tak dalej. Liczba wywołań będzie rosła liniowo, co na szczęście nie jest taką katastrofą jak wzrost wykładniczy, czy nawet kwadratowy, ale wciąż jest to problem. [edit: popełniłem tu błąd -- wzrost jednak będzie wykładniczy, nie liniowy, co stanowi jeszcze większy problem]

Dlatego kod, który napisałem jest poprawny i to jego należy użyć, natomiast do Twojego wkradły się błędy i nie powinno się go używać w ten sposób. Nie powinno się wywoływać setInterval(f, n) z wnętrza funkcji f (chyba że rzeczywiście chcesz wywoływać funkcję f coraz więcej razy, ale wątpię, by Tobie o to chodziło, a na pewno nie chodzi o to autorowi posta). Natomiast konstrukcja ta byłaby w pełni poprawna -- nazwałbym ją nawet pewnym wzorcem -- w przypadku funkcji setTimeout, która jednak działa inaczej niż setInterval.

0
bswierczynski napisał(a)

Liczba wywołań będzie rosła liniowo, co na szczęście nie jest taką katastrofą jak wzrost wykładniczy, czy nawet kwadratowy, ale wciąż jest to problem.

Jesteś pewien? W tym przypadku setInterval działa jak fork, czyli rozgałęzia "wątek" na dwa

0

@tomkiewicz:
Prawda. Po odejściu od kompa pomyślałem sobie o tym i właśnie wróciłem, by o tym napisać ;). Nie mam racji co do liniowego wzrostu liczby wywołań. Sytuacja będzie dużo gorsza: wzrost będzie jednak wykładniczy. W sumie to taki odpowiednik wywoływania forka w pętli (bo do samego forka można porównać setTimeout -- w tym wypadku zresztą bezpieczne). JavaScript tak w ogóle nie ma wątków (tj. jest jednowątkowy), ale też pewnie dlatego umieściłeś to słowo w cudzysłowach.

Z powodu tego wzrostu -- znacznie gorszego niż liniowy -- ten błąd jest jeszcze bardziej niebezpieczny i może prowadzić do szybkiego wyczerpania zasobów (choć nowe przeglądarki powinny temu przeciwdziałać).

0

@bswierczynski:
Wielkie dzięki. Teraz wszystko ładnie działa. Funkcja dewPoint aktualizuje wartości, a o to właśnie mi chodziło.

0

Fakt ^^ Człowiek już nie myśli... (Pomyliłem pojęcia i zapomniałem o setInterval)

1 użytkowników online, w tym zalogowanych: 0, gości: 1