mikrocontroller.net

Forum: PC-Programmierung Javascript Funktionen werden in falscher Reihenfolge ausgeführt


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Ivo -. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich bin gerade dabei, ein Programm zu schreiben (läuft alles im 
Browser), welches ein Javascript-Programm ausführt, zwischen allen 
Befehlen soll aber 500ms gewartet werden. Also habe ich folgenden Code 
geschrieben:
code.replace(/;/g, ";sleep(500);");
var script = document.createElement("script");
script.innerHTML = code;
document.querySelector(body).appendCild(code);

Der Code wird auch richtig erzeugt und eingefügt, allerdings werden am 
Anfang offensichtlich immer alle sleep-Funktionen ausgeführt und dann 
der Rest. Ich habe im Internet nur Sachen im Zusammenhang mit Ajax 
gefunden, davon habe ich allerdings nichts implementiert, ich habe auch 
keine anderen APIs eingebunden, das einzige was ich mache, ist im 
innerHTML von ein paar Elementen imgs zu platzieren, da werden dann 
natürlich Bilder geladen.
Was mache falsch?

Vielen Dank im Vorraus,
Ivo

Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ivo Z. schrieb:
> das einzige was ich mache, ist im innerHTML von ein paar Elementen imgs
> zu platzieren,

Nö, Du machst auch einen Textersatz und fügst "sleep"-Aufrufe ein. Da 
nicht bekannt ist, wie "code" vor dem Textersatz oder nach dem 
Textersatz aussieht, kann man den Rest nur raten.

Ansonsten glaube ich nicht, daß es eine Funktion "appendCild" gibt. 
Steht das wirklich so in Deinem Code drin?

Autor: Ivo -. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vorher sieht code beispielsweise so aus:
var x=100;
greatFunction();

function greatFunction(){
    console.log("Hello");
}
Nach der Textersetzung ist hinter jedem Semikolon eben noch ein 
sleep()-Aufruf.

Ob es appendChild() gibt, weiß ich nicht genau, ich glaube aber schon, 
im richtigen Code habe ich schon ein entsprechendes script-Element was 
ich durch replace() ersetze (das gibts auf jeden Fall)

Ivo

Autor: Ivo -. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
code kann beliebiger JavaScript-Code sein, nur um es nochmal deutlich zu 
machen.

Ivo

Autor: Rolf M. (rmagnus)
Datum:

Bewertung
4 lesenswert
nicht lesenswert
Ivo Z. schrieb:
> Ob es appendChild() gibt,

In deinem Code steht nicht appendChild, sondern appendCild!

> im richtigen Code habe ich schon

Das ist das Problem: Du solltest uns den "richtigen Code" zeigen und 
nicht etwas, das du hier für das Posting nochmal getippt hast. Du willst 
Hilfe bei der Fehlersuche, zeigst aber Code, der andere Fehler enthält 
als der "richtige Code".

Autor: Sascha W. (sascha-w)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
@Ivo,

was willst du damit überhaupt bezwecken?
Könnte es evl. sein das du das Ergebnis deines JS-Codes erst siehst wenn 
der komplett durchgelaufen ist und es deshalb so aussieht als ob nur 
eine Pause gemacht wird?

Sascha

Autor: Ivo -. (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Den richtigen Code findet ihr auf GitHub unter github.com/Ivo04/Kara, 
ich glaube, dort ist allerdings noch nicht der aktuellste Stand 
hochgeladen, muss ich später nochmal machen.

Um einmal den Sinn des ganzen zu erklären:
Evt kennt ihr swisseeuc.ch und die Informatik-Sparte mit den 
Kara-Programmen (dort hat man einen Marienkäfer den man für verschiedene 
Aufgaben programmieren soll). Da ich schon länger programmiere und die 
Übungen die wir in der Schule machen mehr Fingerübung für mich sind, 
hatte mein Info-Lehrer die Idee, dass ich eine eigene Version von Kara 
programmiere (bitte lasst euch jetzt nicht über das deutsche 
Bildingssystem aus), also habe ich mich mal hingesetzt und bin auch 
relativ weit gekommen, jetzt hänge ich eben an diesem Problem und komme 
nicht wirklich weiter, auch Google hat mir bisher nicht geholfen.
Damit der Käfer nicht quasi unsichtbar über das Feld fliegt, will ich 
eine Wartezeit einfügen.

Ivo

Autor: Ivo -. (Gast)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Sascha W. schrieb:
> @Ivo,
>
> was willst du damit überhaupt bezwecken?
> Könnte es evl. sein das du das Ergebnis deines JS-Codes erst siehst wenn
> der komplett durchgelaufen ist und es deshalb so aussieht als ob nur
> eine Pause gemacht wird?
>
> Sascha

Nein, das kann eigentlich nicht sein, aber siehe Github-Code

Ivo

PS: Meinen Info-Lehrer habe ich noch nicht gefragt, ist ja schließlich 
Sonntag, der behauptet aber selber, dass er relativ wenig Ahnung hat und 
ich wahrscheinlich sogar besser als er bin (traurig eigentlich)

Autor: Carl D. (jcw2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ivo Z. schrieb:
> Sascha W. schrieb:
>> @Ivo,
>>
>> was willst du damit überhaupt bezwecken?
>> Könnte es evl. sein das du das Ergebnis deines JS-Codes erst siehst wenn
>> der komplett durchgelaufen ist und es deshalb so aussieht als ob nur
>> eine Pause gemacht wird?
>>
>> Sascha
>
> Nein, das kann eigentlich nicht sein, aber siehe Github-Code
>
> Ivo

In einem Browser-Umfeld schon. Da laufen Scripts als EventHandler und 
sleep() macht man via timeout(). Wenn es dir um Debugging geht, früher 
hat man da alert() benutzt, heute kann jeder Browser (mehr oder weniger 
gut) Script-Debuggung per F12.

Autor: Daniel A. (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sleep funktionen in JS? Das ist unschön, mir sind nur Implementierungen 
bekannt, die 100% CPU während dem warten verbrauchen und alles anhalten.
Nunja, mal abgesehen von der ES7 async Variante, die aber nur in async 
Funktionen geht, die nur in Browsern mit ES7 async support läuft: 
https://jsfiddle.net/pzadtLew/
Es gibt schon einen Grund, warum JS Runtimes keine solche Funktion 
anbieten.
Wozu brauchst du das denn überhaupt? Gibt es keine Alternativen, durch 
den Code in den Debugger Tools des Browsers durch steppen zum Beispiel?

Autor: Gåst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>PS: Meinen Info-Lehrer habe ich noch nicht gefragt, ist ja schließlich
>Sonntag, der behauptet aber selber, dass er relativ wenig Ahnung hat und
>ich wahrscheinlich sogar besser als er bin (traurig eigentlich)

Eigenlob - traurig eigentlich.

Autor: TestX (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
in javascript benutzt man kein sleep (gibt es nicht) sondern 
window.setTimeout!

wenn du etwas wie sleep im code nutzen willst kannst du dir das selber 
bauen oder zB ein npm modul wie async-magic nutzen (es2017 
promise/await)....allerdings fehlen dir hierfür noch die grundlagen.

fang bitte erstmal mit einem js grundlagen tutorial an...atm fehlt es 
bei dir an allen stellen...

Autor: experte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"sleep" im Zusammenhang mit JavaScript hört sich nach Schwachsinn an.

Ein Browser funktioniert so:
1. JavaScript Code ausführen (die Webseite "hängt" solange Javascript 
ausgeführt wird)
2. HTML rendern
3. Auf Event warten (Maus, Tastatur, Netzwerk, Timer). Bei einem Event 
zurück zu 1.

JavaScript kann auch niemals selber auf ein Event warten. JavaScript 
muss dem Browser sagen, bei welchen Events welche Funktion aufgerufen 
werden soll. Das macht man mit den Funktionen addEventHandler, 
setTimeout, requestAnimationFrame etc.

Autor: Ivo -. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gåst schrieb:
> Eigenlob - traurig eigentlich.

Nein, eben kein Eigenlob, mit dem "traurig eigentlich" wollte ich 
vielmehr deitlich machen, dass ich eben nicht supertoll bin, mein Lehrer 
dies aber so sieht und ich eher traurig finde, obwohl ich eben nicht 
supertoll bin, anscheinend besser als er bin (wie gesagt, seine Meinung)

Ivo

Autor: Ivo -. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel A. schrieb:
> Sleep funktionen in JS? Das ist unschön, mir sind nur Implementierungen
> bekannt, die 100% CPU während dem warten verbrauchen und alles anhalten.
Mir auch, leider......

> Wozu brauchst du das denn überhaupt? Gibt es keine Alternativen, durch
> den Code in den Debugger Tools des Browsers durch steppen zum Beispiel?

Die Idee ist gut, da werde ich mich mal informieren, ob das irgendwie 
möglich ist.
Also quasi nach einer Sekunde einen Schritt weiter.

Ivo

Autor: Ivo -. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TestX schrieb:
> fang bitte erstmal mit einem js grundlagen tutorial an...atm fehlt es
> bei dir an allen stellen...

Kannst du das bitte etwas spezifizieren, ich ja lernbereit und 
lernfähig, dafür muss ich aber schon wissen, wo es bei mir hapert.
Also das nächste mal etwas genauer und ich würge sogar ein Danke raus 
;-)

Ivo

Autor: bluppdidupp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibt es in Javascript aktuell überhaupt inzwischen sleep()? 
(Firefox+Chrome sagen bei mir auf Browser-Entwicklerkonsole: nope)

Oder wie hast du die sleep()-Funktion implementiert?

Autor: Theor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ivo Z. schrieb:
> TestX schrieb:
>> fang bitte erstmal mit einem js grundlagen tutorial an...atm fehlt es
>> bei dir an allen stellen...
>
> Kannst du das bitte etwas spezifizieren, ich ja lernbereit und
> lernfähig, dafür muss ich aber schon wissen, wo es bei mir hapert.
> Also das nächste mal etwas genauer und ich würge sogar ein Danke raus
> ;-)

Na, auf die Idee, mit der Giesskanne delays zu streuen wäre Dein Lehrer 
auch gekommen.
Die Kunst besteht darin, an den "richtigen" Stellen, zu verzögern, zu 
wissen ob und warum das eigentlich nötig ist und wie und ob man das in 
JS und mit bestimmten Browsern tun. DA hapert es bei Dir.

Abgesehen davon, tu mir den Gefallen, aufrichtige Dankbarkeit wenigstens 
glaubhaft zu heucheln.

Autor: Ivo -. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bluppdidupp schrieb:
> Gibt es in Javascript aktuell überhaupt inzwischen sleep()?
> (Firefox+Chrome sagen bei mir auf Browser-Entwicklerkonsole: nope)
>
> Oder wie hast du die sleep()-Funktion implementiert?

Nee, gibts leider nicht, ich hab es schon mit mehreren Versionen 
probiert, allerdings auch alle mit 100% CPU, da die async/await bei mir 
irgendwie nicht gefunzt hat, muss ich nochmal gucken. Probiert habe ich 
schon mit Datum erzeugen und solange überprüfen, ob die Zeit schon 
vorbei ist und auch schon ganz primitiv mit einer for-Schleife die bis 
zu einer hohen Zahl zählt.

Das delay-streuen war nur als erster Schritt gedacht, später kommt 
wahrscheinlich ein gezielteres delayen, ich denke mal, ich werde nur 
delays hinter die kara.bewegDich Funktionen setzen.

GlaubhaftHeuchel
In aufrichtiger Dankbarkeit,
Ivo
/GlaubhaftHeuchel

Autor: Sascha W. (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

für das was du vorhast wurde das weiter oben genannte 
requestAnimationFrame gemacht - solltest du dir mal anschauen.

https://javascript.info/js-animation#requestanimationframe

Von einem linearen Programmablauf (mit sleeps) solltest du dich 
allerdings verabschieden.

Sascha

Autor: Joachim S. (oyo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha W. schrieb:
> @Ivo,
>
> was willst du damit überhaupt bezwecken?
> Könnte es evl. sein das du das Ergebnis deines JS-Codes erst siehst wenn
> der komplett durchgelaufen ist und es deshalb so aussieht als ob nur
> eine Pause gemacht wird?

Ich vermute auch stark, dass letztlich genau hier der Hund begraben 
liegt.
sleep gibt es in Browser-Javascript doch eigentlich gar nicht; was auch 
immer da als sleep-Implementierung benutzt wird, wird in der Praxis 
garantiert einfach den gesamten Prozess blockieren. In den minimalen 
Pausen zwischen den blockierenden sleep-Aufrufen wird der Bildschirm 
nicht aktualisiert, sondern erst, wenn alles durchgelaufen ist und die 
sleep-Aufrufe nicht mehr den Prozess blockieren. Daher der irreführende 
Eindruck, es würden zuerst alle sleep-Aufrufe ausgeführt werden, obwohl 
es in Wahrheit gar nicht so ist, sondern nur so wirkt.

Daher mein Tipp:
Versuche es stattdessen doch mal testweise mit der folgenden (von 
stackoverflow kopierten), sinnvollen sleep-Implementierung:
function sleep_nonblocking(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

[...]

code.replace(/;/g, ";await sleep_nonblocking(500);");

Autor: Daniel A. (daniel-a)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Joachim S. schrieb:
> Daher mein Tipp:
> Versuche es stattdessen doch mal testweise mit der folgenden (von
> stackoverflow kopierten), sinnvollen sleep-Implementierung:

Das wird nicht funktionieren. Await ist nur in async Funktionen 
zulässig. Und async Funktionen geben auch immer nur direkt Promises 
zurück, ein einfaches suchen/ersetzen wird da nicht reichen.

Autor: Joachim S. (oyo)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Daniel A. schrieb:
> Joachim S. schrieb:
>> Daher mein Tipp:
>> Versuche es stattdessen doch mal testweise mit der folgenden (von
>> stackoverflow kopierten), sinnvollen sleep-Implementierung:
>
> Das wird nicht funktionieren. Await ist nur in async Funktionen
> zulässig. Und async Funktionen geben auch immer nur direkt Promises
> zurück, ein einfaches suchen/ersetzen wird da nicht reichen.

Verdammt, das ergibt Sinn. ;)

Autor: M.K. B. (mkbit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kommt mir bekannt vor. Ich wollte auch mal meine alten Kara 
Programme aus der Schulzeit von Delphi in JavaScript umsetzen.

In Delphi konnte man einfach den Code laufen lassen und die GUI wurde 
dann regelmäßig mit dem aktuellen Stand angezeigt. Da hatte das Konzept 
mit dem Sleep noch funktioniert.

In JavaScript läuft aber alles in einem Thread und während der läuft 
kann der Browser die Seite nicht rendern. Eine mögliche Lösung wäre, aus 
der Funktion zu springen um mit einem Timeout später wieder 
weiterzumachen. Dazu müsste man sich allerdings den aktuellen Zustand 
merken, weil man nicht einfach wieder in die Funktion zurückspringen 
kann. Spätestens bei rekursiven Funktionen wird es dann häßlich.

Meine Lösung war dann, einen Interpreter für Logo 
https://de.wikipedia.org/wiki/Logo_(Programmiersprache) in JavaScript zu 
schreiben. Der Interpreter führt dann immer so lange Befehle aus, bis 
eine bestimmte Zeitspanne abgelaufen ist. Dann wartet er mit Timeout und 
macht dann mit dem Programm weiter. Für rekursives Zeichnen brauchte der 
Interpreter dann auch noch eine Stack. Den Code habe ich aber aktuell 
nicht zur Hand.

Vielleicht hilft es dir aber weiter, wenn du mal bei Google nach 
JavaScript Logo Interpreter suchst.

Autor: Sheeva P. (sheevaplug)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Gåst schrieb:
> Eigenlob - traurig eigentlich.

Eigentlich, habe ich gehört, sei eigentlich kein Wort.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ivo Z. schrieb:
> var x=100;
> greatFunction();
>
> function greatFunction(){
>     console.log("Hello");
> }
>
> Nach der Textersetzung ist hinter jedem Semikolon eben noch ein
> sleep()-Aufruf.

Du meinst also, dass console.log() instantan "Hello" ausspuckt? Soweit 
ich weiß, wird hier gebuffert (8KB ?). Das würde auch Deinen Eindruck 
erklären:

> allerdings werden am Anfang offensichtlich immer alle sleep-Funktionen
> ausgeführt und dann der Rest.

Autor: micha54 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also ich bezweifle, dass JavaScript sich im Browser wie gewünscht 
verhält.
Ein solches Dokument ist kein lineares Programm. Der Code wird 
ausgeführt, indem ganze Blöcke, also keine einzelnen Statements, dem 
Interpreter zur Ausführung übergeben werden.

Das bedeutet: ein replace mit sleep im code wird vermutlich ignoriert, 
weil der gesamte Block bereits dem Interpreter übergeben wurde.
Was sollte der Interpreter denn tun ?
- Erkennen, dass was geändert wurde ?
- Abbrechen oder bis zum Ende weitermachen
- Wo soll er den geänderten code3 beginnen ? Am Anfang ? An der 
unterbrochenen Stelle ? Ach ja, der code war ja bereits vollständig 
ausgeführt worden, also nicht noch einmal ausführen.

Merkwürdiges Vorgehen, ich bezweifle, dass das im Schulunterricht so 
gelehrt wurde.
Aber ich habe mich ja auch bei meinen Kindern gefragt, wer da wem was 
beibringen könnte.

Gruß,
Michael

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.