NEWS
js callback asynchron problem
-
Hallo,
ich komme seit Tagen mit diesem Problem nicht weiter.
Asynchrone Programmierung ist wohl nicht meine Welt.var Raumctr = 0 // Schleife fĂŒr jeden Raum ###################################### S_Raum.forEach(function(element, index) { if( SollTemp_akt != Temp_FOA && SollTemp_akt != Temp_Abw ){ setState(Out_Root+D_Raum[index]+".Man",SollTemp_akt,true,function(){ setRT(index,element,SollTemp_akt) // function setRT wg. Callback log("RaumzĂ€hlerCB: "+Raumctr+" Index: "+RaumIndex) }) } else { setRT(index,element,SollTemp_akt) log("RaumzĂ€hler: "+Raumctr+" Index: "+RaumIndex) } }); // Schleife fĂŒr jeden Raum ###################################### // Script hier, wenn alle RĂ€ume durchlaufen sind // ########## Script soll hier fortfahren, wenn Schleife fĂŒr jeden Raum durchlaufen ist. ########## log("RaumzĂ€hler nach allen RĂ€umen: "+Raumctr+" Index: "+RaumIndex) Monitor: // wegen dem verzögerten Callback wird folgende Reihenfolge ausgegeben: RaumzĂ€hler: 1 Index: 4 RaumzĂ€hler: 2 Index: 5 RaumzĂ€hler: 3 Index: 6 RaumzĂ€hler: 4 Index: 7 RaumzĂ€hler nach allen RĂ€umen: 4 Index: 7 - zu frĂŒh, im Callback warten noch 4 RĂ€ume RaumzĂ€hlerCB: 5 Index: 0 RaumzĂ€hlerCB: 6 Index: 1 RaumzĂ€hlerCB: 7 Index: 2 RaumzĂ€hlerCB: 8 Index: 3 function setRT(index,element,SollTemp_akt){ Raumctr++ RaumIndex = index }Das Problem dabei:
je nach "if( SollTemp_akt != Temp_FOA && SollTemp_akt != Temp_Abw )" wird die funktion setRT()
einmal direkt oder als callback aufgerufen."// Script hier, wenn alle RĂ€ume durchlaufen sind"
soll aber in jedem Fall erst ausgefĂŒhrt werden, wenn alle RĂ€ume durchlaufen sind.
In dem Beispiel hier wird zuerst die setRT() als Callback aufgerufen, wegen der Verzögerung bei
setState wird der Raumctr aber erst incrementiert, nachdem der anschlieĂende direkte Aufruf von setRT()
schon beendet ist und die Schleife fĂŒr jeden Raum schon beendet wurde. -
Hallo,
ich komme seit Tagen mit diesem Problem nicht weiter.
Asynchrone Programmierung ist wohl nicht meine Welt.var Raumctr = 0 // Schleife fĂŒr jeden Raum ###################################### S_Raum.forEach(function(element, index) { if( SollTemp_akt != Temp_FOA && SollTemp_akt != Temp_Abw ){ setState(Out_Root+D_Raum[index]+".Man",SollTemp_akt,true,function(){ setRT(index,element,SollTemp_akt) // function setRT wg. Callback log("RaumzĂ€hlerCB: "+Raumctr+" Index: "+RaumIndex) }) } else { setRT(index,element,SollTemp_akt) log("RaumzĂ€hler: "+Raumctr+" Index: "+RaumIndex) } }); // Schleife fĂŒr jeden Raum ###################################### // Script hier, wenn alle RĂ€ume durchlaufen sind // ########## Script soll hier fortfahren, wenn Schleife fĂŒr jeden Raum durchlaufen ist. ########## log("RaumzĂ€hler nach allen RĂ€umen: "+Raumctr+" Index: "+RaumIndex) Monitor: // wegen dem verzögerten Callback wird folgende Reihenfolge ausgegeben: RaumzĂ€hler: 1 Index: 4 RaumzĂ€hler: 2 Index: 5 RaumzĂ€hler: 3 Index: 6 RaumzĂ€hler: 4 Index: 7 RaumzĂ€hler nach allen RĂ€umen: 4 Index: 7 - zu frĂŒh, im Callback warten noch 4 RĂ€ume RaumzĂ€hlerCB: 5 Index: 0 RaumzĂ€hlerCB: 6 Index: 1 RaumzĂ€hlerCB: 7 Index: 2 RaumzĂ€hlerCB: 8 Index: 3 function setRT(index,element,SollTemp_akt){ Raumctr++ RaumIndex = index }Das Problem dabei:
je nach "if( SollTemp_akt != Temp_FOA && SollTemp_akt != Temp_Abw )" wird die funktion setRT()
einmal direkt oder als callback aufgerufen."// Script hier, wenn alle RĂ€ume durchlaufen sind"
soll aber in jedem Fall erst ausgefĂŒhrt werden, wenn alle RĂ€ume durchlaufen sind.
In dem Beispiel hier wird zuerst die setRT() als Callback aufgerufen, wegen der Verzögerung bei
setState wird der Raumctr aber erst incrementiert, nachdem der anschlieĂende direkte Aufruf von setRT()
schon beendet ist und die Schleife fĂŒr jeden Raum schon beendet wurde.@hanss
du könntest den Aufruf des 2.setRT ebenfalls in einen Callback mit settimeout setzen, dann werden die Aufrufe zumindes in gleicher Reihenfolge auf den Stack geschrieben.
Allerdings kann die Abarbeitung innerhalb des Callbacks unterschiedlich lange ausfallen. Von daher hast du keine Garantie, das hier genau die gleiche Reihenfolge eingehalten wirdsetTimeout(function(){ setRT(index,element,SollTemp_akt) log("RaumzÀhler: "+Raumctr+" Index: "+RaumIndex) },10);kann man in den Skripten setState nicht auch synchron aufrufen?
-
@hanss
du könntest den Aufruf des 2.setRT ebenfalls in einen Callback mit settimeout setzen, dann werden die Aufrufe zumindes in gleicher Reihenfolge auf den Stack geschrieben.
Allerdings kann die Abarbeitung innerhalb des Callbacks unterschiedlich lange ausfallen. Von daher hast du keine Garantie, das hier genau die gleiche Reihenfolge eingehalten wirdsetTimeout(function(){ setRT(index,element,SollTemp_akt) log("RaumzÀhler: "+Raumctr+" Index: "+RaumIndex) },10);kann man in den Skripten setState nicht auch synchron aufrufen?
-
@OliverIO
Vielen Dank, aber Deine Lösung ist nicht sicher, weil zeitabhÀngig.
Ein synchroner setState wÀre die Lösung, das hÀtte mir zwei Tage rumprobieren erspart. -
Eventuell sind die neuen async-Funktionen in 4.8.x was fĂŒr dich @hanss
https://forum.iobroker.net/topic/36999/neu-diverse-async-funktionen-im-javascript-adapterDamit lÀsst sich der Programmablauf trotz asynchronitÀt schön steuern. Ich hab den obigen Schnipsel mal entsprechend umgebaut. Beachte das
asyncvor der Funktion undawait setStateAsync:async function raumzaehler() { var Raumctr = 0; // Schleife fĂŒr jeden Raum ###################################### for (let i = 0; i < S_Raum.length; i++) { const element = S_Raum[i]; if (SollTemp_akt != Temp_FOA && SollTemp_akt != Temp_Abw) { await setStateAsync(Out_Root + D_Raum[index] + ".Man", SollTemp_akt, true); setRT(index, element, SollTemp_akt); // function setRT wg. Callback log("RaumzĂ€hlerCB: " + Raumctr + " Index: " + RaumIndex); } else { setRT(index, element, SollTemp_akt); log("RaumzĂ€hler: " + Raumctr + " Index: " + RaumIndex); } } // Schleife fĂŒr jeden Raum ###################################### // ########## Script soll hier fortfahren, wenn Schleife fĂŒr jeden Raum durchlaufen ist. ########## log("RaumzĂ€hler nach allen RĂ€umen: " + Raumctr + " Index: " + RaumIndex); } // Funktion aufrufen nicht vergessen! raumzaehler(); -
Eventuell sind die neuen async-Funktionen in 4.8.x was fĂŒr dich @hanss
https://forum.iobroker.net/topic/36999/neu-diverse-async-funktionen-im-javascript-adapterDamit lÀsst sich der Programmablauf trotz asynchronitÀt schön steuern. Ich hab den obigen Schnipsel mal entsprechend umgebaut. Beachte das
asyncvor der Funktion undawait setStateAsync:async function raumzaehler() { var Raumctr = 0; // Schleife fĂŒr jeden Raum ###################################### for (let i = 0; i < S_Raum.length; i++) { const element = S_Raum[i]; if (SollTemp_akt != Temp_FOA && SollTemp_akt != Temp_Abw) { await setStateAsync(Out_Root + D_Raum[index] + ".Man", SollTemp_akt, true); setRT(index, element, SollTemp_akt); // function setRT wg. Callback log("RaumzĂ€hlerCB: " + Raumctr + " Index: " + RaumIndex); } else { setRT(index, element, SollTemp_akt); log("RaumzĂ€hler: " + Raumctr + " Index: " + RaumIndex); } } // Schleife fĂŒr jeden Raum ###################################### // ########## Script soll hier fortfahren, wenn Schleife fĂŒr jeden Raum durchlaufen ist. ########## log("RaumzĂ€hler nach allen RĂ€umen: " + Raumctr + " Index: " + RaumIndex); } // Funktion aufrufen nicht vergessen! raumzaehler();ich habe immer wieder probleme mit dem async und await - toll wĂ€re es, wenn man so was wie mit dem type-script kurs fĂŒr adapterentwickler machen wĂŒrde - nur halt fĂŒr dieses thema
-
ich habe immer wieder probleme mit dem async und await - toll wĂ€re es, wenn man so was wie mit dem type-script kurs fĂŒr adapterentwickler machen wĂŒrde - nur halt fĂŒr dieses thema
-
@AlCalzone danke werd ich mal durcharbeiten
-
ich habe immer wieder probleme mit dem async und await - toll wĂ€re es, wenn man so was wie mit dem type-script kurs fĂŒr adapterentwickler machen wĂŒrde - nur halt fĂŒr dieses thema
@liv-in-sky sagte in js callback asynchron problem:
....wenn man so was wie mit dem type-script kurs fĂŒr adapterentwickler machen wĂŒrde....
gibt es dazu einen Link?
-
@liv-in-sky sagte in js callback asynchron problem:
....wenn man so was wie mit dem type-script kurs fĂŒr adapterentwickler machen wĂŒrde....
gibt es dazu einen Link?
-
@liv-in-sky cool, Danke!
-
Eventuell sind die neuen async-Funktionen in 4.8.x was fĂŒr dich @hanss
https://forum.iobroker.net/topic/36999/neu-diverse-async-funktionen-im-javascript-adapterDamit lÀsst sich der Programmablauf trotz asynchronitÀt schön steuern. Ich hab den obigen Schnipsel mal entsprechend umgebaut. Beachte das
asyncvor der Funktion undawait setStateAsync:async function raumzaehler() { var Raumctr = 0; // Schleife fĂŒr jeden Raum ###################################### for (let i = 0; i < S_Raum.length; i++) { const element = S_Raum[i]; if (SollTemp_akt != Temp_FOA && SollTemp_akt != Temp_Abw) { await setStateAsync(Out_Root + D_Raum[index] + ".Man", SollTemp_akt, true); setRT(index, element, SollTemp_akt); // function setRT wg. Callback log("RaumzĂ€hlerCB: " + Raumctr + " Index: " + RaumIndex); } else { setRT(index, element, SollTemp_akt); log("RaumzĂ€hler: " + Raumctr + " Index: " + RaumIndex); } } // Schleife fĂŒr jeden Raum ###################################### // ########## Script soll hier fortfahren, wenn Schleife fĂŒr jeden Raum durchlaufen ist. ########## log("RaumzĂ€hler nach allen RĂ€umen: " + Raumctr + " Index: " + RaumIndex); } // Funktion aufrufen nicht vergessen! raumzaehler();Async und await machen aus asynchronen Funktionen wieder synchrone Funktionen.
Das will er ja nicht -
Async und await machen aus asynchronen Funktionen wieder synchrone Funktionen.
Das will er ja nichtHier mal ein kurzer Artikel, der auf einen Punkt eingeht, der die Funktionsweise der asynchronen Funktionen (callback oder auch promise basiert) erklÀrt
https://dev.to/steelvoltage/if-javascript-is-single-threaded-how-is-it-asynchronous-56gd
-
Async und await machen aus asynchronen Funktionen wieder synchrone Funktionen.
Das will er ja nicht@OliverIO
Vielen Dank, ich habe das jetzt so gelöst:In die Funktion setRT() einen RaumzĂ€hler und das Script eingefĂŒgt, wenn alle RĂ€ume durchlaufen sind:
Das ist sehr ĂŒbersichtlich und nicht so kompliziert wie async und await.
Ich glaube, das kapier ich nicht mehr.setRT() { Raumctr++ //mein Script if (S_Raum.length == Raumctr){ // letzter Raum // Script hier, wenn alle RĂ€ume durchlaufen sind Raumctr=0 } } -
Async und await machen aus asynchronen Funktionen wieder synchrone Funktionen.
Das will er ja nicht@OliverIO wieso nicht? Wenn man etwas ausfĂŒhren will, nachdem asynchrone VorgĂ€nge durch sind, ist async/await genau das richtige Mittel.
Und IMO intuitiver als der callback Krempel. Nach dem Aufruf mit await ist es einfach fertig. -
@OliverIO wieso nicht? Wenn man etwas ausfĂŒhren will, nachdem asynchrone VorgĂ€nge durch sind, ist async/await genau das richtige Mittel.
Und IMO intuitiver als der callback Krempel. Nach dem Aufruf mit await ist es einfach fertig.@AlCalzone
Ah hatte einer seiner Antworten falsch interpretiert. Hab nochmal gelesen.
Wenn er mit seiner Lösung nun zufrieden ist, ist ja alles gut
Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.
Hast du es satt, bei jedem Besuch durch die gleichen BeitrĂ€ge zu scrollen? Wenn du dich fĂŒr ein Konto anmeldest, kommst du immer genau dorthin zurĂŒck, wo du zuvor warst, und kannst dich ĂŒber neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und BeitrĂ€ge positiv bewerten, um anderen Community-Mitgliedern deine WertschĂ€tzung zu zeigen.
Mit deinem Input könnte dieser Beitrag noch besser werden đ
Registrieren Anmelden