NEWS
Javascript - async function - wie ist die Reihenfolge
-
Hallo.
Habe mir in Blockly ein kleines Script gebaut und in Javascript umgewandelt.
Dabei kommt der Code auf dem Screenshot raus.
Das Script beinhaltet eine "async function".
Was bedeutet das genau? Können die einzelnen Schritte asynchron, also nicht nacheinander ausgeführt werden?
Wichtig wäre für mich, dass die Zeilen 14-21 unbedingt nacheinander in der Reihenfolge ausgeführt werden.
Es darf also nicht vorkommen, dass z.B. die Zeile 17 vor der Zeile 16 ausgeführt wird.
Kann mir einer sagen ob das so gegeben ist?
Danke -
-
@ente34 OK danke, ist da sicher sehr gut erklärt^^ kapiere es aber trotzdem nicht
-
@atifan Die Zeilen werden schon nacheinander ausgeführt. async (und await) ist dann maßgeblich, wenn nicht synchron gearbeitet werden darf. Kleines Beispiel:
Funktion "A" ließt eine Webseite ein (dauert zB. 2 Sekunden)
Funktion "B" soll nun aus dieser Webseite eine Temperatur heraus parsenStehen die im JS nun einfach hintereinander, ist Funktion "A" noch mit dem einlesen beschäftigt, während Funktion "B" schon die Temperatur auslesen möchte (die Funktionen werden synchron aufgerufen) --> geht natürlich schief
Also "sagt" man der Funktion "B" höflich mittels "await", warte doch bitte bis die Asynchrone Funktion "A" "Fertig" meldet und führe sie dann erst aus. Grob erklärt
-
@atifan sagte in Javascript - async function - wie ist die Reihenfolge:
@ente34 OK danke, ist da sicher sehr gut erklärt^^ kapiere es aber trotzdem nicht
das ist auch ein sehr komplexes Thema und ohne eigene Übungen nur schwer zu verstehen. Wills du das eig. in Blockly oder JS machen?
mit
await setStateAsync()
sollte das eigentlich funktionieren -
@atifan sagte: Wichtig wäre für mich, dass die Zeilen 14-21 unbedingt nacheinander in der Reihenfolge ausgeführt werden.
Die Reihenfolge wird durch async function nicht verändert.
-
Hi, Danke für eure Antworten.
Bei euren Beispielen geht es aber um mehrere Funktionen, also Funktion A und Funktion B.
Ich verstehe das schon, dass wenn Funktion A noch nicht fertig ist, die Funktion B bereits fertig sein kann, also async.
Aber in meinem Fall ist es ja nur eine Funktion unter der dann aber mehrere Schritte abgearbeitet werden.
Die Frage ist halt, werden innerhalb der Funktion die Schritte in der Reihenfolge abgearbeitet?
Wenn ich @fastfoot richtig verstehe ist das ja so, d.h. Zeile 14-21 werden auf jeden Fall nacheinander abgearbeitet.
Das wäre das was für mich wichtig ist.@fastfoot: Ob Blockly oder Javascript wäre mir eigentlich egal, Hauptsache es funktioniert so wie ich es will^^.
Ich kann halt kein Javascript und habe es deswegen als Blockly erstellt und dann in Javascript umgewandelt um hier zu verdeutlichen worum es gehtPS: In meinem Beispiel oben kommen zwar 2 Funktionen vor, die werden aber sowieso unabhängig voneinander getriggert.
-
@atifan sagte in Javascript - async function - wie ist die Reihenfolge:
Wenn ich @fastfoot richtig verstehe ist das ja so, d.h. Zeile 14-21 werden auf jeden Fall nacheinander abgearbeitet.
Das wäre das was für mich wichtig ist.da hast du mich falsch verstanden
So wie von dir gezeigt laufen die Funktionen(innerhalb der einen Funktion) asynchron, so weit ich das beurteilen kann. @paul53 kann das sicher besser beurteilen, ich würde eine JS-Funktion nehmen, bin aber jetzt sehr unsicher damit
-
@atifan sagte: Zeile 14-21 werden auf jeden Fall nacheinander abgearbeitet.
Ja, die Zeilen werden in der Reihenfolge nacheinander abgearbeitet. setState() arbeitet zwar asynchron, aber wichtig ist die Reihenfolge für das synchrone getState().
-
@paul53 und @fastfoot
Vorab:
Ich habe zwar schon einige Jahre "Programmiererfahrung", auch mit objektorientierter Programmierung und ereignisgesteuertem Programmablauf, bin aber kein Profi und würde mich in Java Script / Node, als Anfänger bezeichnen, weshalb ich in der Regel Blockly benutze.Ich habe ähnliche Verständnisschwierigkeiten, wie @atifan, deshalb möchte ich mich hier ´mal einbringen/einmischen:
Es nützt doch nichts, daß getState synchron arbeitet, denn es ist bei @atifan in Zeile 14-21 doch "nur das Argument" des asynchronen setStates - oder?
Weil @ente24 oben auf die Erklärugen von @AlCalzone verwiesen hat, bringe ich hier ´mal auch meine eigene Fragestellung mit ein, in der Hoffnung, daß das Thema "Reihenfolge bei der Skriptzeilen-Abarbeitung" ´mal grundsätzlich er-/geklärt werden kann:
Wenn ich es richtig verstanden habe, wurde mit dem/einen der letzten Updates des Adapters "Script Engine" dieser komplett neugestaltet, um die "(Programmier)-Technik" mit dem "async/await" einzuführen/zu ermöglichen - richtig?
Aber mir ist folgendes aufgefallen:
Wenn ich mir ein Blockly-Skript, das einen Funktionsblock "nach etwas tun ... gib zurück" beinhaltet und das ich vor einigen Monaten erstellt habe, als JS-Code anzeigen lasse, steht dort "function ...".
Schreibe ich jetzt (also nach dem Update des Adapters) solch ein Blockly-Skript, steht dort "async function ...". D. h. das Blockly-Funktions-Objekt scheint sich geändert zu haben, da es jetzt offenbar anderen JS-Code erzeugt!?Auch wenn ich das mit dem "async/await" noch nicht anwenden kann, weil mir dazu noch Wissen/Erfahrung fehlt, verstehe ich schon, wozu das gut ist (Funktionen/Prozesse können parallel abgearbeitet werden, ohne daß ein wartender Prozeß andere blockiert.). Ich begreife aber (noch) nicht, warum man nun offenbar keine Möglichkeit mehr hat, mit Blockly eine Funktion zu erstellen, die nicht "async" ist.
Kann da jemand weiterhelfen?
Und dann noch eine zweite Sache, die mit der Thematik vermutlich auch irgendwie zusammenhängt:
Ich habe einen Homematic-Füllstandssensor in meiner Zisterne. Leider ist die Warnung bei leer werdender Batterie nicht immer zuverlässig, so daß es vorkam, daß der Sensor einfach keine Werte mehr lieferte ohne vorher eine Batteriewarnung auszugeben. Man wundert sich dann, daß die Zisterne leer ist, obwohl die Anzeige noch Wasservorrat suggeriert.
Ich habe daher ein Blockly geschrieben, daß tagsüber jede Stunde getriggert wird und nachschauen soll, ob der Zeitstempel des letzten empfangenen Meßwertes nicht älter als 1/2 Stunde ist (Der Sensor steht auf "alle 3minuten einen Wert senden".) und falls doch, eine Warnung ausgibt.
Nun kommt es vor, daß diese Warnung kommt, obwohl der letzte Zeitstempel erst drei Minuten alt ist, der Sensor also gar nicht ausgefallen war.
Das kann bei dem benutzten Blockly/Programmcode meiner Ansicht nach nur dadurch erklärt werden, daß das Holen des aktuellen Zeitstempels in Zeile 12 zwar "angestoßen" wurde, jedoch noch kein Ergebnis geliefert hat, bevor dann in Zeile 16 der aktuelle mit dem letzten Zeitstempel verglichen wird. (Dadurch steht dann beim Vergleich in aktueller_Zeitstempel noch immer der Wert von vor einer Stunde und fürht zu dem nicht gewollten Vergleichsergebnis.)
Wenn getState wirklich synchron arbeitet, verstehe ich das nicht, denn synchron würde für mich bedeuten, daß das Skript solange in Zeile 12 bleibt, bis getState ein Ergebnis geliefert hat - oder wie verhält es sich wirklich?Kann das jemand genauer erklären?
var vorheriger_Zeitstempel, aktueller_Zeitstempel; // Die Batteriemeldung des Füllstandssensors scheint nicht sicher zu erfolgen. // Um einen Ausfall der Messung frühzeitig zu bemerken, // prüft dieses Skript hier stündlich, ob der Sensor (soll ca. alle 3 Minuten senden) noch neue Werte sendet. // // Variable 1h rückwärts initialisieren, sodaß bei erstem Routinenstart keine Meldung ausgelöst wird. (Nervt sonst.) vorheriger_Zeitstempel = (new Date().getTime()) - 3600000; console.log(vorheriger_Zeitstempel); schedule('{"time":{"start":"05:10","end":"23:59","mode":"hours","interval":1},"period":{"days":1}}', async function () { aktueller_Zeitstempel = getState("hm-rpc.0.QEQ4711.1.FILLING_LEVEL").ts; // Prüfen, ob der "aktuelle" Zeitstempel "neu genug" ist. // Da jede Stunde geprüft wird und der Sensor ca. alle 3Minuten sendet, sollte der "aktuelle" Zeitstempel mindestens 30Minuten neuer sein, als der zuvor von diesem Skript gespeicherte. // 30 Minuten sind 1.800.000 Tausendstelsekunden. if (aktueller_Zeitstempel > vorheriger_Zeitstempel + 1800000) { // Sensor scheint noch neue Werte zu schicken. setState("0_userdata.0.Zisterne.Füllstandssensor.Ausfall"/*Zisterne.Füllstandssensor.Ausfall*/, false, true); vorheriger_Zeitstempel = (new Date().getTime()); console.log((['Zisterne-Füllstandssensor: Sensor scheint noch neue Werte zu schicken.','Neu gesetzter vorheriger Zeitstempel: ',vorheriger_Zeitstempel].join(''))); } else { // Der "aktuelle" Zeitstempel ist nicht "neu genug". // Nur, wenn Ansage erwünscht. if (getState("0_userdata.0.Zisterne.Füllstandssensor.Überwachungsansage").val) { setState("0_userdata.0.Zisterne.Füllstandssensor.Ausfall"/*Zisterne.Füllstandssensor.Ausfall*/, true, true); setState("hm-rpc.0.OEQ0815.1.SUBMIT"/*MP3_Ausgabe:1.SUBMIT*/, (String(getState("hm-rega.0.2777").val) + ',1,108000,110')); console.log(('Zisterne-Füllstandssensor: Der "aktuelle" Zeitstempel ist nicht "neu genug": ')); } } console.log((['Zisterne-Füllstandssensor: Letzte Meldung war ',formatDate(getDateObject(aktueller_Zeitstempel), "DD.MM.YYYY"),' ',formatDate(getDateObject(aktueller_Zeitstempel), "hh:mm:ss.sss")].join(''))); });
-
Hi wollte auch nochmal nen Zwischenstand geben.
Ich hab meine Scripte jetzt so geändert, dass jede Zeile durch einen eigenen Cron, jeweils immer mit 5 Sekunden Verzögerung zum vorherigen Cron getriggert wird.
Hoffe das die 5 Sek ausreichen und dadurch sichergestellt wird, dass alles nacheinander ausgeführt wird.
Geht programmiertechnisch bestimmt auch schöner, aber mir ist das wichtigste das es macht was es soll, der Rest ist Nebensache -