NEWS
Javascript Funktion triggert ungewollt, wie verhindern?
-
evtl. kann mir jemand einen Tipp geben. Ich rufe von meiner Heizung Werte via RS232 ab, das Schema lautet: Anfrage senden, Antwort empfangen, Pause, Nächster Anfrage...
Für jede Abfrage habe ich eine eigene Funktion geschrieben, welche einzeln aufgerufen, auch funktionieren. Das Problem ist: Wenn ich die Funktionen hintereinander aufrufe (1000ms Pause dazwischen), dann wird bei der vorher aufgerufenen Funktion der Empfang auch immer mit getriggert. Also ich sende Data2, Data1 empfängt aber auch was... Im Log sieht das dann so aus:
22:23:01.009 info javascript.0 (37498) script.js.common.Test-1: Data1 send: ce3c0000f2
22:23:01.165 info javascript.0 (37498) script.js.common.Test-1: Data1 received: 02ce0325ea
22:23:02.009 info javascript.0 (37498) script.js.common.Test-1: Data2 send: 1101000010
22:23:02.153 info javascript.0 (37498) script.js.common.Test-1: Data1 received: 0211000112
22:23:02.154 info javascript.0 (37498) script.js.common.Test-1: Data2 received: 0211000112Wieso ist die Funktion denn noch "scharf"? Die sollte doch garnicht anspringen. Ich kapier's nicht...
function FetchTemperatureExternal() { port.write(buffer1, function(err) { if (err) { return log('Error on write: ', err.message); } log('Data1 send: ' + buffer1.toString('hex')); }); const parser1 = port.pipe(new ByteLength({ length: 5 })); parser1.on('data', function (data1) { console.log('Data1 received: ' + data1.toString('hex')); }); } function FetchControllerMode1() { port.write(buffer2, function(err) { if (err) { return log('Error on write: ', err.message); } log('Data2 send: ' + buffer2.toString('hex')); }); const parser2 = port.pipe(new ByteLength({ length: 5 })); parser2.on('data', function (data2) { console.log('Data2 received: ' + data2.toString('hex')); }); }
-
@spaceduck Gibt es Befehle wie port.close, port.open?
-
@spaceduck versuche mal statt
on()
die Funktiononce()
zu verwenden - falls es die gibt. -
parser1.on('data',
fügt bei jedem Aufruf einen zusätzlichen Handler für das "data"-Event hinzu. D.h. jedes Mal wenn du die Funktion aufrufst, wird der definierte Callback einmal mehr als beim letzten Mal aufgerufen.
Die Parser-Instanzen bleiben so auch bestehen, damit baust du dir nach und nach ein Memory-Leak.Korrekt wäre, beim Initialisieren einmal die Handler zu definieren und dann nicht pollen (jede Sekunde aufrufen), sondern auf eingehende Daten zu reagieren.
-
@AlCalzone said in Javascript Funktion triggert ungewollt, wie verhindern?:
fügt bei jedem Aufruf einen zusätzlichen Handler für das "data"-Event hinzu. D.h. jedes Mal wenn du die Funktion aufrufst, wird der definierte Callback einmal mehr als beim letzten Mal aufgerufen.
Die Parser-Instanzen bleiben so auch bestehen, damit baust du dir nach und nach ein Memory-Leak.Danke für die Erklärung, macht Sinn!
Der Controller sendet nur auf Anfrage, d.h. ich schicke einen Befehl, bekomme die Antwort fertig.
Es werden keine zyklischen Werte gesendet worauf ich reagieren kann, daher muss ich das so lösen - es sei denn ich übersehe was (bin Javascript Anfänger). -
@UncleSam said in Javascript Funktion triggert ungewollt, wie verhindern?:
@spaceduck versuche mal statt
on()
die Funktiononce()
zu verwenden - falls es die gibt.Jo, super das klappt tatsächlich! Ich danke Dir!
17:24:01.007 info javascript.0 (24840) script.js.common.Test-1: Data1 send: ce3c0000f2 17:24:01.172 info javascript.0 (24840) script.js.common.Test-1: Data1 received: 02ce024886 17:24:03.007 info javascript.0 (24840) script.js.common.Test-1: Data2 send: 1101000010 17:24:03.179 info javascript.0 (24840) script.js.common.Test-1: Data2 received: 0211000112
-
@spaceduck sagte in Javascript Funktion triggert ungewollt, wie verhindern?:
daher muss ich das so lösen
Das kann man schon so strukturieren, dass du nicht für jeden Befehl einen neuen Handler registrieren musst.
Mit once ist es vermutlich einfacher.Dennoch empfehle ich dir dringend, folgende Zeilen aus den Funktionen auszulagern und insgesamt nur 1x auszuführen:
const parser1 = port.pipe(new ByteLength({ length: 5 }))
Zwei verschiedene Parser, die gleich aufgebaut sind, brauchst du auch nicht (
parser1, parser2
).So wie du es derzeit machst, hast du nach jedem Aufruf einen zusätzlichen Parser, der mit Daten gefüttert wird. Nur sind alle bis auf den letzten unnötig, da du sie nicht auswertest.
Nach 10 Aufrufen hast du dann 9 Stück, die Daten verarbeiten aber nicht genutzt werden. Nach 1000 Aufrufen sinds 999...
-
@AlCalzone
Danke erstmal, die Lernkurve ist steil...
Ich habe jetzt in beiden Funktionen nur noch "const parser = port..." -> Wäre das auch OK oder starte ich damit auch mit jedem Aufruf einen neuen Parser? -
Auch damit startest du mit jedem Aufruf einen neuen Parser. Mein Vorschlag: Ziehe die Erstellung des Parsers raus, dorthin wo du den Port erstellst.
In den Funktionen kannst du dann jeweils einen einmal-Handler mitonce
anhängen und nutzen. -
@AlCalzone
Danke Dir, hab es jetzt so umgesetzt und es klappt. -
@spaceduck Kannst du dann bitte Deine Lösung hier dokumentieren. Danke.