Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. Asynchron bzw mir fehlt der Lösungsansatz

NEWS

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    17
    1
    2.1k

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    13
    1
    929

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    25
    1
    2.2k

Asynchron bzw mir fehlt der Lösungsansatz

Geplant Angeheftet Gesperrt Verschoben Skripten / Logik
7 Beiträge 3 Kommentatoren 591 Aufrufe
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • BlackmikeB Offline
    BlackmikeB Offline
    Blackmike
    schrieb am zuletzt editiert von
    #1

    ich habe folgendes Progrämmchen, welches mir die maximales Ventilöffnung von Heizkörperventilen eines Gewerkes ermitteln soll

    
    $('[state.id=*.VALVE_STATE](functions=Ventil_Anbau)').on (function (obj) {
        var MaxValve=-1;
        $('[state.id=*.VALVE_STATE](functions=Ventil_Anbau)').each (function (id, i) {
            getState (id, function (error,oID) {
                if (oID.val>MaxValve) {
                    MaxValve= oID.val; 
                }
                log (oID.val + ", "+ MaxValve);
            });
        });
        log ("Maximal: " + MaxValve);
    });  
    

    sieht logisch aus, tuts aber leider nicht, da die $.each asychron läuft

    Der Aufruf tuts, aber wenn die Routine durchläuft, ergibt sich folgende Ausgabe

    Maximal: -1

    16, 16

    5, 16,

    32, 32

    8, 32

    Fragestellung:

    Wie kriege ichs hin, das Ausgabe von Maximal (später dann ein setState () ) das Schleifenergebnis ausgibt ?

    Danke für hilfreiche Ideen, Gruss und guten Rutsch, Black

    die Wahrheit ist ein Chor aus Wind

    1 Antwort Letzte Antwort
    0
    • AlCalzoneA Offline
      AlCalzoneA Offline
      AlCalzone
      Developer
      schrieb am zuletzt editiert von
      #2

      Disclaimer: Alles ungetestet!

      @Blackmike:

      Wie kriege ichs hin, das Ausgabe von Maximal (später dann ein setState () ) das Schleifenergebnis ausgibt ? `
      Die $-Funktion gibt ein Array zurück, das um ein paar Funktionen (on/each/…) erweitert wurde. Du kannst also vorher die Länge abfragen und dann beim letzten Eintrag die finale Logik ausführen:

      ! ````
      var valveIDs = $('state.id=*.VALVE_STATE');
      ! valveIDs.on(function (obj) {
      var MaxValve=-1;
      valveIDs.each(function (id, i) {
      getState(id, function (error,oID) {
      if (oID.val>MaxValve) {
      MaxValve = oID.val;
      }
      log(oID.val + ", "+ MaxValve);

              if (i === valveIDs.length - 1) {
                  log ("Maximal: " + MaxValve);
                  // Weiterer Code, der zum Abschluss der Prüfung ausgeführt wird
              }
          });
      });
      

      });

      ! ````
      Ich würde aber behaupten, dass nicht die .each-Funktion asynchron ausgeführt wird, sondern dass dein Problem daher kommt, dass du die asynchrone Variante von getState (mit Callback) verwendest. Einfacher geht es so:

      ! ````
      var valveIDs = $('state.id=*.VALVE_STATE');
      ! valveIDs.on(function (obj) {
      var MaxValve=-1;
      valveIDs.each(function (id, i) {
      // Hier liegt der Hase im Pfeffer:
      var curVal = getState(id);

          if (curVal > MaxValve) {
              MaxValve = curVal;
          }
          log(curVal + ", "+ MaxValve);       
      });
      
      log ("Maximal: " + MaxValve);
      // Weiterer Code, der zum Abschluss der Prüfung ausgeführt wird
      

      });

      Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

      1 Antwort Letzte Antwort
      0
      • BlackmikeB Offline
        BlackmikeB Offline
        Blackmike
        schrieb am zuletzt editiert von
        #3

        ok, dann werde ich das mal angehen.

        ich habe alle getstates bei mir aber asynchron, ich habe 3 javascript adapter bei mir laufen, 1* produktiv, 1* device wrapper und 1* spiele und test adapter. der Unterschied bei load und CPU Temp mit haken bei "nicht alle Zustände bei Start abonieren" ist deutllich.

        von daher fände ich es nett, wenn es eine trickreichemöglichkeit gäbe, einen asychronen block irgendwie zu kapseln.

        ich werd deinen Ansatz mal testen, thnx erstmal, Black

        die Wahrheit ist ein Chor aus Wind

        1 Antwort Letzte Antwort
        0
        • paul53P Offline
          paul53P Offline
          paul53
          schrieb am zuletzt editiert von
          #4

          @Blackmike:

          ich habe alle getstates bei mir aber asynchron, `
          Dann solltest Du auch wissen, wie man damit umgeht. Für alle anderen gibt es die synchrone Version.

          Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
          Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

          1 Antwort Letzte Antwort
          0
          • paul53P Offline
            paul53P Offline
            paul53
            schrieb am zuletzt editiert von
            #5

            @AlCalzone:

                        if (i === valveIDs.length - 1) {
                            log ("Maximal: " + MaxValve);
                            // Weiterer Code, der zum Abschluss der Prüfung ausgeführt wird
                        }
            ```` `  
            

            Das wird wahrscheinlich auch nicht funktionieren, da i schneller durchgezählt wird als die callbacks abgearbeitet sind.

            EDIT: So sollte es funktionieren:

            ! var valveIDs = $('[state.id=*.VALVE_STATE](functions=Ventil_Anbau)'); ! valveIDs.on(function (obj) { var MaxValve=-1; var j = 0; valveIDs.each(function (id, i) { getState(id, function (error,oID) { if (oID.val>MaxValve) { MaxValve = oID.val; } log(oID.val + ", "+ MaxValve); j++; if (j === valveIDs.length) { log ("Maximal: " + MaxValve); // Weiterer Code, der zum Abschluss der Prüfung ausgeführt wird } }); }); }); !

            Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
            Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

            1 Antwort Letzte Antwort
            0
            • AlCalzoneA Offline
              AlCalzoneA Offline
              AlCalzone
              Developer
              schrieb am zuletzt editiert von
              #6

              @paul53:

              Das wird wahrscheinlich auch nicht funktionieren, da i schneller durchgezählt wird als die callbacks abgearbeitet sind. `
              Hast Recht. Dann bleibt noch außerhalb der each-Funktion eine Zählervariable zu definieren und diese bei jedem Callback-Aufruf zu erhöhen. Ist diese gleich der Array-Länge, sind wir fertig.

              @Blackmike:

              von daher fände ich es nett, wenn es eine trickreichemöglichkeit gäbe, einen asychronen block irgendwie zu kapseln. `
              Da deine asynchronen Funktionen alle auf eine gemeinsame Variable zugreifen, besteht eventuell die Gefahr einer race-condition. Das kannst du auf verschiedene Weisen umgehen.

              1. Indem du dir selbst eine "Funktionsschleife" baust:
              <list type="decimal">4. Statt .each auf dem ersten Array-Element getState aufrufen.

              1. Im Callback das erste Element aus dem Array entfernen.

              2. Ist das Array nun leer, bist du fertig. Sonst zurück zu 1.
                Das Prinzip (ohne getState) wird z.B. im zwave-Adapter angewendet (funktion doFix) https://github.com/ioBroker/ioBroker.zw … in.js#L635

              Finde ich persönlich nicht so schön, da die eigentliche Aufgabe im Loop-Konstrukt verwaschen wird. Ich bevorzuge Promises:

              2. Mit Promises arbeiten

              Dazu musst du eine promisifizierte Version der getState-Funktion erstellen, nennen wir sie mal getStateP. Geht z.B. mit dieser Helfer-Funktion:

              (Ab NodeJS 6) https://github.com/AlCalzone/ioBroker.t … ises.js#L6

              (NodeJS 4) https://github.com/AlCalzone/ioBroker.g ... ises.js#L3

              const getStateP = promisify(getState);
              
              

              Dann erstellst du dir aus den State-IDs ein Array aus Promises

              const getStatePromises = valveIDs.map(id => getStateP(id));
              
              

              Darauf wartest du nun

              Promise.all(getStatePromises).then(results => {
                  // results ist ein Array mit den Werten deiner States
                  // Hier synchron weiterarbeiten
                  const MaxValve = Math.max(results); // kein Einzelvergleich nötig!
                  // Irgendwas mit dem Ergebnis machen
              }).catch(e => {
                  // Fehler behandeln
              });
              
              

              Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

              1 Antwort Letzte Antwort
              0
              • BlackmikeB Offline
                BlackmikeB Offline
                Blackmike
                schrieb am zuletzt editiert von
                #7

                thnx, wieder einiges gelernt…

                die Wahrheit ist ein Chor aus Wind

                1 Antwort Letzte Antwort
                0
                Antworten
                • In einem neuen Thema antworten
                Anmelden zum Antworten
                • Älteste zuerst
                • Neuste zuerst
                • Meiste Stimmen


                Support us

                ioBroker
                Community Adapters
                Donate

                728

                Online

                32.6k

                Benutzer

                82.2k

                Themen

                1.3m

                Beiträge
                Community
                Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                ioBroker Community 2014-2025
                logo
                • Anmelden

                • Du hast noch kein Konto? Registrieren

                • Anmelden oder registrieren, um zu suchen
                • Erster Beitrag
                  Letzter Beitrag
                0
                • Home
                • Aktuell
                • Tags
                • Ungelesen 0
                • Kategorien
                • Unreplied
                • Beliebt
                • GitHub
                • Docu
                • Hilfe