Timer zu lahm
Manu
- javascript
0 JürgenB0 Sven Rautenberg0 Norbert0 Manu
Nabend...
Ich habe einen JS-Timer, der mir die Wartezeit bei einer Auswertung etwas versüßen soll - kleiner Spaß - er soll neben einem loading.gif zeigen, dass auch nach einer Ewigkeit noch etwas im Hintergrund passiert.
Dem erbsenzählenden Kunden ist nun natürlich aufgefallen, dass dieser Timer viel zu langsam läuft. Ich hab nun nicht wirklich eine Idee, wie ich diesen mit der Systemzeit abgleichen kann. Jemand von Euch vielleicht?
Le code:
function showProcessingTime(myElement,mseconds,seconds,minutes,hours) {
var myDiv = document.getElementById(myElement);
if(minutes > 59) {
minutes = 0;
hours += 1;
} else {
if (seconds > 59){
seconds = 0;
minutes += 1;
} else {
seconds += 1;
/*
if(mseconds >= 9) {
mseconds = 0;
seconds += 1;
} else {
mseconds += 1;
}
*/
}
}
var pres = (seconds < 10) ? '0' : '';
var prem = (minutes < 10) ? '0' : '';
var preh = (hours < 10) ? '0' : '';
myDiv.innerHTML = preh + hours +":"+ prem + minutes +":"+ pres + seconds;
if(bProcessingTime) {
an = setTimeout("showProcessingTime('"+ myElement +"',"+ mseconds +","+ seconds +","+ minutes +","+ hours +")",1000);
}
}
Gruß,
Manu
Hallo Manu,
zur Timeout-Zeit kommt jedesmal noch die Rechenzeit des Scriptes hinzu. Versuch doch mal setInterval. Dann wird die Funktion im festen Zeittakt aufgerufen.
Gruß, Jürgen
Hello out there!
zur Timeout-Zeit kommt jedesmal noch die Rechenzeit des Scriptes hinzu. Versuch doch mal setInterval. Dann wird die Funktion im festen Zeittakt aufgerufen.
Das konnte meine Versuche damit nicht bestätigen. [</archiv/2005/10/t117840/#m755518>]
Dann kannst du sogar ein sehr beliebiges, auch kleineres, Zeitintervall für die Zeitanzeige nehmen, weil bei genau 1000 Millisekunden - plus Ausführungszeit für die Funktion - sich durchaus der Fall ergeben kann, dass die Zeitanzeige mal um zwei Sekunden springt.
Bei einem _beliebigen_ kleineren Zeitintervall (sagen wir 950 ms) kann es auch sein, dass die Anzeige mal um zwei Sekunden springt. Oder dass sie mal fast zwei Sekunden lang einfriert. [</archiv/2005/10/t117840/#m755304> ff.]
Die Ausführungszeit kann aber gemessen werden und der Wert als recht genauer Schätzwert für die nächste Ausführung genommen werden. [</archiv/2005/10/t117840/#m755480> f., http://gunnarbittersmann.de/2005/weltzeituhr.html]
See ya up the road,
Gunnar
Hallo Gunnar,
Die Ausführungszeit kann aber gemessen werden und der Wert als recht genauer Schätzwert für die nächste Ausführung genommen werden. [</archiv/2005/10/t117840/#m755480> f., http://gunnarbittersmann.de/2005/weltzeituhr.html]
Ich habe als mein erstes AJAX-Projekt ja mal ein Countdown-Script ("noch 5 Minuten und 13 Sekunden bis zur Schnäppchenmöglichkeit") geschrieben, das die clientseitig heruntergezählte Zeit einmal in der Minute auf die serverseitig ausgelieferte Zeit synchronisierte. Darüber hinaus habe ich für AJAX auch noch kaum sinnvolle Verwendung gefunden.
So groß waren die Datenmengen nämlich nie, die ich erst auf Nachfrage hätte nachladen wollen, als dass ich sie nicht auch von vornherein beim ersten Mal versteckt auf Vorrat hätte laden lassen können.
Gruß Gernot
Hello,
So groß waren die Datenmengen nämlich nie, die ich erst auf Nachfrage hätte nachladen wollen, als dass ich sie nicht auch von vornherein beim ersten Mal versteckt auf Vorrat hätte laden lassen können.
Bei einer hierarchischen Auswahl können die Datenmengen ganz schnell expolieren, wenn man man alles Präventiv mitsenden wollte. Da bietet sich dann doch besser eine vernünftig geführte Session und jeweils ein neuer Request an.
Eben diesen macht AJAX dann schon mal automatisch im Hintergrund. Es gibt sogar Seiten, auf denen das einwandfrei funktioniert, und keine (unsichtbare) Endlosschleife produziert wird.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hallo Gunnar,
da war ich wohl zu naiv. Bei einer anderen Programmiersprache habe ich mit Intervallen sehr gute Erfahrung machen können. Daher dachte ich, der setInterval im JS würde sich auch auf einen festen Takt synchronisieren.
Nach deiner Antwort habe ich auch einen Test durchgeführt und dabei festgestellt, das unter Last sowohl die per setTimeout als auch die per setInterval gestarteten Funktionen sich "hinten anstellen" und erst ausgeführt werden, wenn andere Funktionen fertig sind. Und wenn die Laufzeit dieser Funktionen größer ist, als die Intervallzeit, kommt die Intervallfunktion doch nur einmal. Offensichtlich ist setInterval nur ein Ableger von setTimeout. Und IE und FF verhalten sich auch noch unterschiedlich schlecht.
Hier die Links zu meinen Tests:
Lastfunktion läuft kürzer als Intervallzeit
http://www.j-berkemeier.de/test/ZeitTest_k.html
Lastfunktion läuft auch länger als Intervallzeit
http://www.j-berkemeier.de/test/ZeitTest_l.html
Achtung: beide Tests belasten eine CPU zu 100%!
Gruß, Jürgen
Moin!
Nach deiner Antwort habe ich auch einen Test durchgeführt und dabei festgestellt, das unter Last sowohl die per setTimeout als auch die per setInterval gestarteten Funktionen sich "hinten anstellen" und erst ausgeführt werden, wenn andere Funktionen fertig sind.
Richtig. Und logisch. Javascript ist keine Multitasking-Programmiersprache, es kann immer nur eine Codestelle zur Zeit ausgeführt werden. Wenn also eine aufwendige Schleife noch aktiv ist, wird trotz setTimeout oder setInterval diese Schleife nicht unterbrochen, sondern das Ende dieses Skriptteils abgewartet.
Ansonsten wäre Javascript deutlich komplexer zu programmieren, weil man sich mit der möglichen Unterbrechung an jeder beliebigen Stelle herumschlagen müßte. Dieses explizite Single-Task-Prinzip führt zu extremer Einfachheit.
- Sven Rautenberg
Hallo Sven,
ich hatte allerdings erwartet, das setInterval alle n Millisekunden einen Auftrag in die Schlange stellt und so wenigstens versucht, synchron zu bleiben. Beim FF könnte das der Fall sein, beim IE wohl eher nicht. Da scheint setInterval durch setTimeout realisiert worden zu sein.
Gruß, Jürgen
Moin!
ich hatte allerdings erwartet, das setInterval alle n Millisekunden einen Auftrag in die Schlange stellt und so wenigstens versucht, synchron zu bleiben. Beim FF könnte das der Fall sein, beim IE wohl eher nicht. Da scheint setInterval durch setTimeout realisiert worden zu sein.
Das würde ja doch aber in die Katastrophe führen, wenn das, was man regelmäßig ausführen will, länger dauert, als das Zeitintervall von setInterval. Dann sammeln sich die Aufträge an, während die CPU-Last des ständig laufenden Javascripts den Rechner u.U. unbenutzbar langsam macht.
- Sven Rautenberg
Hallo Sven,
Das würde ja doch aber in die Katastrophe führen, wenn das, was man regelmäßig ausführen will, länger dauert, als das Zeitintervall von setInterval. Dann sammeln sich die Aufträge an, während die CPU-Last des ständig laufenden Javascripts den Rechner u.U. unbenutzbar langsam macht.
das stimmt natürlich. Die Zahl der wartenden Prozesse müsste dann begrenzt werden. Wobei die Frage bleibt, was willkürlicher wäre, Intervalle einfach länger zu machen als angegeben, oder bei Bedarf Intervalle zu überspringen um den Takt einzuhalten. Beides nicht optimal.
Ich habe in dieser Diskussion auf jeden Fall einiges über die Timerfunktionen von JS dazugelernt, hoffentlich Manu auch, um sein Problem zu lösen.
Gruß, Jürgen
Moin!
Dem erbsenzählenden Kunden ist nun natürlich aufgefallen, dass dieser Timer viel zu langsam läuft. Ich hab nun nicht wirklich eine Idee, wie ich diesen mit der Systemzeit abgleichen kann. Jemand von Euch vielleicht?
Indem du das Date-Objekt nach der Client-Uhrzeit bzw. dem realen Zeitverbrauch befragst, und nicht die Funktionsaufrufe zählst, die durch setTimeout zwar im Sekundentakt GEPLANT werden, aber nicht im Sekundentakt AUFGERUFEN werden.
Dann kannst du sogar ein sehr beliebiges, auch kleineres, Zeitintervall für die Zeitanzeige nehmen, weil bei genau 1000 Millisekunden - plus Ausführungszeit für die Funktion - sich durchaus der Fall ergeben kann, dass die Zeitanzeige mal um zwei Sekunden springt.
- Sven Rautenberg
Hallo Sven,
danke für Deine Antwort (und die der anderen natürlich auch)...
Ja, dass ich date() verwenden muss, um die Zeiten synchron zu halten war mich einigermaßen klar, nur wie ich das abgleiche nicht...
Die Idee (weiter unten) jede Minute zu synchronisieren finde ich ganz ok, wie ich das umsetze ist dann die Frage: beim Start die Startzeit ermitteln, mitgeben und jede Minute (oder alle 60 Durchläufe) vergleichen...dass dann der Timer 'springt' ist natürlich nicht so schön...
Gruß,
Manu
Ja, dass ich date() verwenden muss, um die Zeiten synchron zu halten war mich einigermaßen klar, nur wie ich das abgleiche nicht...
Warum willst du denn Abgleichen?
Die Idee (weiter unten) jede Minute zu synchronisieren finde ich ganz ok, wie ich das umsetze ist dann die Frage: beim Start die Startzeit ermitteln, mitgeben und jede Minute (oder alle 60 Durchläufe) vergleichen...
Nein, einfach die aktuelle Zeit ermitteln, fertig.
Struppi.
Warum willst du denn Abgleichen?
Weil:
reele Zeit: 19min
Timer Zeit: 13min
Nein, einfach die aktuelle Zeit ermitteln, fertig.
date() und fertig? :) Konnte mich aber ob anderer Probleme diesem (winzigen) noch nicht widmen...
Gruß,
Manu
Warum willst du denn Abgleichen?
Weil:
reele Zeit: 19min
Timer Zeit: 13min
Schon klar, das eine ist die Laufzeit, das andere die Uhr - was willst du ermitteln?
Nein, einfach die aktuelle Zeit ermitteln, fertig.
date() und fertig? :) Konnte mich aber ob anderer Probleme diesem (winzigen) noch nicht widmen...
Date() und fertig, damit hast du die aktuelle Zeit, soweit ich das verstehe ist es das was du willst, oder?
Struppi.
Nee, was ich will ist ein Timer, der nicht nach schon 19min um 6min abweicht.
Ich versuche das jetzt mal mit
an = setTimeout("showProcessingTime('"+ myElement +"',"+ mseconds +","+ seconds +","+ minutes +","+ hours +")",1000 - (new Date().getMilliseconds()));
Gruß,
Manu
Nee, was ich will ist ein Timer, der nicht nach schon 19min um 6min abweicht.
Das tut er nur, wenn deine Prozedur für den Browser lange dauert, wenn ich mit setInterval eine kurze Prozedur aufrufe und den Interval nicht zu klein wähle, kann ich keine Abweichung in der Größenordnung festellen.
Struppi.
Nee, was ich will ist ein Timer, der nicht nach schon 19min um 6min abweicht.
Beim der letzten Nachricht hab ich mal einen Timer gestartet:
var c = 0;
var interval = 500;
var toMin = function(ms) {
return (ms / (1000 * 60)).toFixed(2)
}
function timerFunk() {
c++;
var out = 'Zeit: ' + toMin((new Date()) - start)
+ '<br>'
+ toMin(c * interval)
;
var o = document.getElementById('out');
o.innerHTML = out;
}
var start = new Date();
window.setInterval(timerFunk, interval);
Das ist der aktuelle Stand:
Zeit: 11.93
11.89
Struppi.
Hai Manu,
Dem erbsenzählenden Kunden ist nun natürlich aufgefallen, dass dieser
Timer viel zu langsam läuft.
ach ...
Ich hab nun nicht wirklich eine Idee, wie ich diesen mit der Systemzeit
abgleichen kann. Jemand von Euch vielleicht?
hmm,
warum willst Du unbedingt eine eigene Zeit creieren?
Nimm doch einfach die Systemzeit und zeige sie an ...
Z.B.:
<script type="text/javascript">
var TG = Array('So.','Mo.','Di.','Mi.','Do.','Fr.','Sa.');
function zeitanzeige() {
var zll = document.getElementById('ZA');
var akt = new Date();
var out = ' ' + TG[(akt.getDay())];
out += ' ' + get_ziff(akt.getDate()) + '.' + get_ziff(akt.getMonth()) + '.' + get_ziff(akt.getYear()) + ' -';
out += ' ' + get_ziff(akt.getHours()) + ':' + get_ziff(akt.getMinutes()) + ':' + get_ziff(akt.getSeconds()) + ' ';
zll.innerHTML = out;
window.setTimeout("zeitanzeige()", 999);
}
function get_ziff(ZL) {
var EG = '0' + ZL;
var xx = EG.length - 2;
return EG.substr(xx,2);
}
window.setTimeout("zeitanzeige()", 999);
</script>
Gruss Norbert
Hallo Norbert,
die Idee ist nicht schlecht, aber ich würde das eher für einen anderen Bereich benutzen. Meine Auswertung kann schonmal eine halbe Ewigkeit dauern - da möchte ich dem User zeigen, wie lange das dauert. Daher der Timer...
Gruß,
Manu