Funktion periodisch aufrufen mit "SetTimeout"
Robert
- javascript
Hallo,
Wenn ich irgendeine Javascript-Funktion
regelmäßig in bestimmte Zeitabständen
mit setTimeout ausführen möchte, dann
funktioniert das leider nicht so, wie ich's
gerne möchte. Zuerst hab' ich's mit
folgendem Script versucht:
<script language="JavaScript">
<!--
for(var i = 0; i <= 1000; i++)
window.setTimeout("irgendwas()",100);
//-->
</script>
Das Problem ist aber, daß dabei nur eine
einzige (keine wiederholte) Verzögerung
von 100 mS stattfindet. Wie es aussieht
wird so die ganze For-Schleife sofort
1000 mal durchlaufen, und 100 mS später
wird 1000 mal die Funktion aufgerufen.
Daraufhin hab' ich's mit folgender Änderung
probiert:
<script language="JavaScript">
<!--
for(var i = 0; i <= 1000; i++)
window.setTimeout("irgendwas()",100*i);
//-->
</script>
So funktioniert's zwar, aber es gibt andere
Probleme. Ich wollte hinter die For-Schleife
noch einen weiteren Befehl setzen, der erst
nach den 1000 Timeouts ausgeführt werden
sollte, aber er wurde sofort ausgeführt.
Anscheinend finden auch hier die 1000
Schleifen-Durchläufe sofort statt, wobei
der Computer die ganzen Daten für die
1000 planten Funktionsaufrufe sich
anscheinend irgendwie merkt und dann
gleich mit dem Script fortfährt, bevor
die ganzen Funktionsaufrufe stattfinden.
Da denke ich, das könnte den PC schnell
überfordern, wenn man z.B. die Zahl der
Schleifen-Durchläufe noch deutlich erhöht.
Nun meine Fragen:
Gibt es eine Möglichkeit, die den Browser
dazu veranlasst die Timeout-Zeit jeweils
abzuwarten, bevor das Script weiter gelesen
und ausgeführt wird? (Also ähnlich, wie z.B.
bei "alert" das Script ja auch erst weiter
ausgeführt wird, wenn man die Meldung
bestätigt hat.) Eine Art Wait-Befehl gibt
es ja bei JS nicht, aber vielleicht kann man
sowas ja irgendwie simulieren?
Wie ich gesehen habe, macht man das manchmal
über Funktionen, die sich selbst aufrufen, aber
das soll ja auch nicht so optimal sein, da für jeden
weiteren Funktionsaufruf zusätzlicher Speicherplatz
verbraucht wird, und nach meinen Überlegungen
müßten solche Scripte grundsätzlich nach einiger
Zeit abstürzen, denn jeder Funktionsaufruf ist ja
ein kleines Unterprogramm, und so werden dann
ja endlos viele Unterprogramme inneinander
verschachtelt. (Vor allem wenn die Anzahl nicht
wie in meinem Beispiel auf 1000 begrenzt wird.)
Wie sieht nun die korrekte Lösung aus, um eine
Funktion immer wieder periodisch in konstanten
Zeitabständen aufzurufen?
Für Eure Hilfe im Vorraus besten Dank.
Bye, Robert
Hallo du da draußen,
ich würds so machen:
window.setTimeout(irgendwas(), 100);
function irgendwas()
{
for(i=0; i <= 1000; i++)
{
// Irgendwas
}
}
Den Rest kannst du vergessen.
Die Pause erzeugst du z. B. eine For-Schleife, z. B. so:
for(i = 0; i < 100000000; i++)
{
//Irgendwas sinnloses, z. B.
0 == 0;
}
Grüße von hier drinnen, aus Biberach an der Riss,
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname4.png" border=0 alt="">
Hallo du da draußen,
man muss es natürlich so machen(kleiner Denkfehler):
var i = 0;
interval = window.setTimeout("irgendwas()", 100);
function irgendwas()
{
if(i >= 1000)
window.clearTimeout(interval);
// http://de.selfhtml.org/javascript/objekte/window.htm#clear_timeout
else
{
// Irgendwas
}
}
Grüße von hier drinnen, aus Biberach an der Riss,
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname5.png" border=0 alt="">
Moin, Dogfish!
Ich frage mich, wie lange dein Spielchen noch so gehen soll? Probierst du gerade ein Schrifttypenprogramm aus? Oder spielst du mit PhotoShop/Gimp/MS Paint herum?
Deine Namensgrafiken sehen zwar alle sehr schön aus, werden aber immer größer.
Kleine Auflistung:
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname.png" border=0 alt="">
250 x 87 pixels, 19 KB
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname2.png" border=0 alt="">
336 x 106 pixels, 48 KB
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname3.png" border=0 alt="">
246 x 96 pixels, 17 KB
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname4.png" border=0 alt="">
554 x 210 pixels, 67 KB
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname5.png" border=0 alt="">
540 x 196 pixels, 97 KB
Noch nicht verwendet wurden:
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname6.png" border=0 alt="">
554 x 210 pixels, 132 KB
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname7.png" border=0 alt="">
674 x 330 pixels, 81
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname8.png" border=0 alt="">
500 x 156 pixels, 69 KB
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname9.png" border=0 alt="">
500 x 156 pixels, 69 KB
<img src="http://mitglied.lycos.de/cdauthunstable/bilder/Grafiken/myname10.png" border=0 alt="">
554 x 210 pixels, 154 KB
Wunderbar, jetzt haben wir alle Bilder gesehen - du kannst dich dann bitte wieder auf Bilder unter 20 KB beschränken (gerne auch auf Dateigrößen kleiner als 5 KB) - manche Menschen hier im Forum müssen ein Modem benutzen oder Traffic zahlen, und die sind sicherlich nicht begeistert, 150 KB-Banner runterzuladen. Da ist die Toleranzgrenze weit überschritten IMO.
Ich danke für dein Verständnis.
- Sven Rautenberg
Hallo,
man muss es natürlich so machen(kleiner Denkfehler):
Ich versteh jetzt leider nicht, wie dieses
Script funktionieren soll, und was die
clearTimeout-Anweisung bringen soll.
Ich hab's eben getestet. Das macht nur einen
einzigen Funktionsaufruf. Da ist doch gar
keine Schleife oder Wiederholung drin?!?
(Der Wert i wird auch nirgends verändert.)
Bye, Robert
Hi there!
[quotation rearranged]
Ich hab's eben getestet. Das macht nur einen
einzigen Funktionsaufruf. Da ist doch gar
keine Schleife oder Wiederholung drin?!?
(Der Wert i wird auch nirgends verändert.)
Weil da immer noch ein Fehler ist. Er wollte die setInterval()-Funktion statt setTimeout() benutzen.
Ich versteh jetzt leider nicht, wie dieses
Script funktionieren soll, und was die
clearTimeout-Anweisung bringen soll.
Mit setInterval() ist das clearInterval() ganz doll noetig, sonst wird Deine Funktion bis in alle Ewigkeit immer weiter aufgerufen.
Ein Alternative waere, am Ende der aufgerufenen Funktion wieder genauso einen setTimout()-Aufruf hinzusetzen, um dafuer zu sorgen, dass die Funktion weitere 100ms spaeter wieder aufgerufen wird. Das ist nicht dasselbe, wie das sofortige rekursive Aufrufen der Funktion, deshalb entsteht da auch kein Problem mit dem Stack, wie Du im ersten Posting vermutet hast.
So long
--
If we do not believe in freedom of speech for people we despise then we don't believe in it at all.
-- Noam Chomsky
Hallo,
Weil da immer noch ein Fehler ist.
Er wollte die setInterval()-Funktion
statt setTimeout() benutzen.
Ah ja, Danke für den Hinweis.
Die setInterval-Funktion kannte ich
noch nicht. Scheint aber für solche
Aufgaben das optimale zu sein.
Bye, Robert
hallo du da drinnen,
nur eine Randbemerkung:
gehts mit der Signaturgrafik (die du zwar in Form und Erscheinungsweise, nicht aber in der Größe in den nachfolgenden postings verändert hast) nicht doch _geringfügig_ kleiner? Eine Signaturgrafik als solche ist durchaus eine gute Idee, aber sie muß nicht derart groß ausfallen ...
schönste Grüße
Christoph S.
Hallo.
<script language="JavaScript">
<!--
for(var i = 0; i <= 1000; i++)
window.setTimeout("irgendwas()",100);
//-->
</script>
Das Problem ist aber, daß dabei nur eine
einzige (keine wiederholte) Verzögerung
von 100 mS stattfindet. Wie es aussieht
wird so die ganze For-Schleife sofort
1000 mal durchlaufen, und 100 mS später
wird 1000 mal die Funktion aufgerufen.
Richtig.
Daraufhin hab' ich's mit folgender Änderung
probiert:
<script language="JavaScript">
<!--
for(var i = 0; i <= 1000; i++)
window.setTimeout("irgendwas()",100*i);
//-->
</script>
So funktioniert's zwar, aber es gibt andere
Probleme. Ich wollte hinter die For-Schleife
noch einen weiteren Befehl setzen, der erst
nach den 1000 Timeouts ausgeführt werden
sollte, aber er wurde sofort ausgeführt.
Dann schreib hinter die Schleife doch einfach:
window.setTimeout("wasandres()",100*i);
Nach dem Schleifendurchlauf ist i nämlich 1001.
Anscheinend finden auch hier die 1000
Schleifen-Durchläufe sofort statt, wobei
der Computer die ganzen Daten für die
1000 planten Funktionsaufrufe sich
anscheinend irgendwie merkt und dann
gleich mit dem Script fortfährt, bevor
die ganzen Funktionsaufrufe stattfinden.
Ja, so sollte das auch sein.
Da denke ich, das könnte den PC schnell
überfordern, wenn man z.B. die Zahl der
Schleifen-Durchläufe noch deutlich erhöht.
Nö, wieso denn? Im Grunde genommen ist das nichts anderes, als wenn du alle 100ms hingehst und auf nen Knopp drückst, der die Funktion ausührt.
Nun meine Fragen:
Gibt es eine Möglichkeit, die den Browser
dazu veranlasst die Timeout-Zeit jeweils
abzuwarten, bevor das Script weiter gelesen
und ausgeführt wird?
Nein, d.h. nicht ohne ein bissel rumzubasteln.
Die einfachste Möglichkeit wäre wohl, das, was nach dem Timeout passieren soll, in ne eigene Funktion zu packen und diese ebenfalls mit einem window.setTimeout aufzurufen.
(Also ähnlich, wie z.B.
bei "alert" das Script ja auch erst weiter
ausgeführt wird, wenn man die Meldung
bestätigt hat.)
Darauf kann man sich auch nicht verlassen, in Opera z.B. läuft das Script im Hintergrund weiter, auch wenn ein Meldungsfenster erscheint.
Eine Art Wait-Befehl gibt
es ja bei JS nicht, aber vielleicht kann man
sowas ja irgendwie simulieren?
Wie schon gesagt, alles in Funktionen packen und dann gesondert per window.setTimeout aufrufen:
<script type="text/javascript">
<!--
function part1()
{
window.alert("Erster Teil-Abschnitt");
window.setTimeout("part2()",5000);
window.alert("Gleich kommt der Zweite.");
}
function part2()
{
window.alert("Zweiter Teil-Abschnitt");
window.setTimeout("window.alert('ENDE')",2000);
}
part1();
//-->
</script>
Von leeren Schleifen ist aber abzuraten, zum einen unterscheidet sich die Bearbeitungszeit der Browser (vermutlich stark) voneinander und zum andern mag ich Meldungen wie "Ein Skript auf dieser Seite verursacht eine Verzögerung..." nicht wirklich.
Wie ich gesehen habe, macht man das manchmal
über Funktionen, die sich selbst aufrufen, aber
das soll ja auch nicht so optimal sein, da für jeden
weiteren Funktionsaufruf zusätzlicher Speicherplatz
verbraucht wird, und nach meinen Überlegungen
müßten solche Scripte grundsätzlich nach einiger
Zeit abstürzen, denn jeder Funktionsaufruf ist ja
ein kleines Unterprogramm, und so werden dann
ja endlos viele Unterprogramme inneinander
verschachtelt. (Vor allem wenn die Anzahl nicht
wie in meinem Beispiel auf 1000 begrenzt wird.)
Alles richtig, so liefert z.B.
<script type="text/javascript">
<!--
function foo()
{
foo();
}
foo();
//-->
</script>
einen "stack overflow", bzw. "out of memory at line...", bzw. "too much recursion", o.ä.
Um sowas zu verhindern kann man dann window.setTimeout verwenden:
<script type="text/javascript">
<!--
function foo()
{
window.setTimeout("foo()",0);
}
foo();
//-->
</script>
Das Script wird dann nicht mehr von sich selbst aufgerufen, sondern vom Timeout.
Wie sieht nun die korrekte Lösung aus, um eine
Funktion immer wieder periodisch in konstanten
Zeitabständen aufzurufen?
Entweder mit window.setTimeout:
<script type="text/javascript">
<!--
function foo()
{
document.bgColor = (document.bgColor == "#ffffff") ? "#000000" : "#ffffff"; // Was für's Auge
window.setTimeout("foo()",500);
}
foo();
//-->
</script>
Wobei die Funktion hier sofort gestartet wird, oder mit window.setInterval:
<script type="text/javascript">
<!--
function foo()
{
document.bgColor = (document.bgColor == "#ffffff") ? "#000000" : "#ffffff";
}
window.setInterval("foo()",500);
//-->
</script>
Hier wird erst 500ms gewartet, und dann startet der erste Funktionsaufruf.
Gruß
Norbert
Hallo,
richtig ist, "irgendwas nur einmal aufzurufen, und am Ende per und nicht gleich 100 Aufrufe in dem browser zu setzen.
abbrechen kannst du jederzeit, z.B. durch Mitzählen einer globalen Variablen oder per Mausclick usw.
Also:
<script language="JavaScript">
<!--
var Zaehler=0
function Schleife() {
//
// jetz mach mal was
//
Zaehler++
if (Zaehler==1000) { // nu mach was anders }
if (Zaehler <1000) {
window.setTimeout("Schleife()",100)
}
}
//-->
</script>
... onLoad=Schleife() ...
Gruß
Hans35