Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. Gültigkeitsbereich Variablen

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    Gültigkeitsbereich Variablen

    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      spider_01 last edited by spider_01

      Hallo allerseits,

      ich habe ein grundsätzliches Verständnisproblem beim Gültigkeitsbereich von Variablen. Auch nach stundenlangem Lesen unzähliger Tutorials bin ich offenbar zu blöd...

      Vielleicht kann mir ja jemand etwas "Starthilfe" anhand eines konkreten Beispiels (Bsp. vereinfacht für bessere Lesbarkeit) geben:

      let aussenTemp = 'hm-rpc.0.NEQ1382028.1.TEMPERATURE';
      
      function lesenTemp(tempID){
          let tempMax = -100;
          log("initial: " + tempMax);
      
          let end = new Date();
          end.setHours(23,59,59,999);
          end.setDate(end.getDate() - 1 ); // gestern
          let start = new Date(end);
          start.setHours(0,0,0,0);
      
          sendTo('sql.0', 'getHistory', {
              id: tempID,
              options: {
                  start:      start,
                  end:        end,
                  aggregate: 'none',
                  addId: true
              }
          }, function (result) {
                  if (!result.error){
                      tempMax = result.result[0].val;
                      log("innere function: " + tempMax);
                  }
              }
          );
          log("aussen: " + tempMax);
      }
      
      lesenTemp(aussenTemp);
      

      Das Beispiel erzeugt folgende Ausgabe:

      19:40:47.421	info	javascript.0 (17473) script.js.common.test.sqlTest: initial: -100
      19:40:47.422	info	javascript.0 (17473) script.js.common.test.sqlTest: aussen: -100
      19:40:47.429	info	javascript.0 (17473) script.js.common.test.sqlTest: innere function: 6
      

      Wie kann ich in dem Beispiel den Rückgabewert der SQL-Abfrage nach "außen" weitergeben? Wenn ich z.B. mit dem Ergebnis mehrerer Abfragen weiterarbeiten möchte und nicht nur dieses eine Ergebnis innerhalb der Rückgabe function benötige...

      Ein "return" bringt auch keinen Erfolg, da er ja nicht in die function "lesenTemp" zurückspringt, sondern... ...tja, wohin genau?

      Schonmal vielen Dank, falls es jemand schafft, das auch mir verständlich zu erklären... 😵

      haus-automatisierung 1 Reply Last reply Reply Quote 0
      • haus-automatisierung
        haus-automatisierung Developer Most Active @spider_01 last edited by haus-automatisierung

        @spider_01 sagte in Gültigkeitsbereich Variablen:

        Wie kann ich in dem Beispiel den Rückgabewert der SQL-Abfrage nach "außen" weitergeben?

        Das Problem ist, dass dein Callback (welcher ja auch nur als Parameter an "sendTo" übergeben wird, erst nach dem Log ausgeführt wird. Einfacher wäre es, auf die Ausführung zu warten und mit Promises zu arbeiten (also der Async-Variante).

        Den Code musst Du so lesen: "Hier ist die Aufgabe, wenn Du fertig bist, ruf bitte diese Funktion auf, ich mache aber schonmal weiter." Deswegen ja auch der Callback. Würde die Logik synchron ausgeführt, könnte man ja mit einem einfachen Rückgabewert arbeiten.

        1 Reply Last reply Reply Quote 0
        • haus-automatisierung
          haus-automatisierung Developer Most Active last edited by haus-automatisierung

          So z.B. (kein Anspruch auf Vollständigkeit, nur kurz um Forum getippt)

          const aussenTemp = 'hm-rpc.0.NEQ1382028.1.TEMPERATURE';
           
          async function lesenTemp(tempID) {
              let tempMax = -100;
              log('initial: ' + tempMax);
           
              const end = new Date();
              end.setHours(23, 59, 59, 999);
              end.setDate(end.getDate() - 1); // gestern
          
              const start = new Date(end);
              start.setHours(0, 0, 0, 0);
            
          
              try {
                  const result = await sendToAsync('sql.0', 'getHistory', {
                      id: tempID,
                      options: {
                          start:      start,
                          end:        end,
                          aggregate: 'none',
                          addId: true
                      }
                  });
          
                  tempMax = result.result[0].val;
                  log('aussen: ' + tempMax);
              } catch (err) {
                  console.error(err);
              }
          }
            
          lesenTemp(aussenTemp);
          

          Stichworte für Google sind:

          • Async/Await
          • JavaScript Promises
          • Promise vs. Callback
          S 2 Replies Last reply Reply Quote 0
          • S
            spider_01 @haus-automatisierung last edited by

            @haus-automatisierung: Herzlichen Dank für die schnelle Rückmeldung!!!

            So z.B. (kein Anspruch auf Vollständigkeit, nur kurz um Forum getippt)

            Kein Problem, bin für jede Hilfe dankbar!

            Stichworte für Google sind:

            • Async/Await
            • JavaScript Promises
            • Promise vs. Callback

            Oha, daran bin ich auf meiner Recherche auch schon vorbeigekommen. Bisher mit mäßigem Erfolg, was mein Verständnis betrifft...

            Aber hilft ja nix, muss da wohl doch noch viiiel mehr Zeit investieren.

            Werde erstmal versuchen, Dein Bsp. nachzuvollziehen. Nochmal Danke!

            haus-automatisierung 1 Reply Last reply Reply Quote 0
            • haus-automatisierung
              haus-automatisierung Developer Most Active @spider_01 last edited by

              @spider_01 sagte in Gültigkeitsbereich Variablen:

              Bisher mit mäßigem Erfolg, was mein Verständnis betrifft...

              Kann verwirrend sein, ist aber eigentlich ganz einfach. Mach Dir ein paar Beispiele mit setTimeout und Promises. Dann wird das schnell klar. Also ganz unabhängig vom ioBroker - reines JavaScript.

              function start() {
                  setTimeout(() => {
                      console.log('jetzt');
                  }, 1000);
              }
              
              start();
              console.log('ende');
              

              Da wird ja auch eine Funktion als Callback übergeben, aber der Code wird weiter ausgeführt. Es wird also erst ende ausgegeben und eine Sekunde später jetzt.

              Wenn Du darauf warten möchtest, musst Du ein Promise zurückgeben.

              function start() {
                return new Promise(resolve => {
                  setTimeout(() => {
                      console.log('jetzt');
                      resolve();
                  }, 1000);
                });
              }
              
              start();
              console.log('ende');
              

              Davon hast Du erstmal nix gewonnen, aber Du kannst eben mit dem Promise weiter machen:

              function start() {
                return new Promise(resolve => {
                  setTimeout(() => {
                      console.log('jetzt');
                      resolve();
                  }, 1000);
                });
              }
              
              start()
                .then(() => {
                  console.log('ende');
                });
              

              .then() wird ausgeführt, wenn das Promise erfüllt wird. Also resolve aufgerufen wird. Dann kannst Du weiter machen. Natürlich könntest Du auch Daten übergeben:

              function start() {
                return new Promise(resolve => {
                  setTimeout(() => {
                      resolve('jetzt');
                  }, 1000);
                });
              }
              
              start()
                .then((ergebnis) => {
                  console.log(ergebnis);
                  console.log('ende');
                });
              

              Und async/await ist einfach nur eine andere Schreibweise, damit man das nicht mit .then schachteln muss.

              async function start() {
                return new Promise(resolve => {
                  setTimeout(() => {
                      resolve('jetzt');
                  }, 1000);
                });
              }
              
              async function wrapper() {
                const ergebnis = await start();
                console.log(ergebnis);
                console.log('ende');
              }
              
              wrapper();
              

              Etwas schwierig zu verstehen ist nun eventuell, dass man await nicht auf der "obersten" Ebene im Code verwenden kann (geht im ioBroker schon, aber dann beschwert sich ggf. die IDE). Immer wenn Du await verwendest, musst die umliegende Funktion mit async gekennzeichnet sein.

              Schau auch noch try/catch vs .error() an (zusammen mit reject).

              S 1 Reply Last reply Reply Quote 0
              • S
                spider_01 @haus-automatisierung last edited by

                @haus-automatisierung

                Hab's mal versucht (sträflicherweise ohne try/catch), und hänge an zwei Punkten:

                 const aussenTemp = 'hm-rpc.0.NEQ1382028.1.TEMPERATURE';
                
                async function lesenTemp(tempID){
                    let tempMax = -100;
                    log("initial: " + tempMax);
                
                    const end = new Date();
                    end.setHours(23,59,59,999);
                    end.setDate(end.getDate() - 1 ); // gestern
                    const start = new Date(end);
                    
                    start.setHours(0,0,0,0);
                
                    const result = await sendTo('sql.0', 'getHistory', {
                        id: tempID,
                        options: {
                            start:      start,
                            end:        end,
                            aggregate: 'none',
                            addId: true
                        }
                    });
                    log (result);
                //    log("aussen: " + tempMax);
                }
                
                lesenTemp(aussenTemp);
                

                Zum einen scheint

                const result = await sendTo('sql.0', 'getHistory', {
                

                nicht so zu funktionieren, wie ich das erwartet hätte, denn die Ausgabe lautet

                21:38:15.535	info	javascript.0 (17473) Stop script script.js.common.test.sqlTest
                21:38:15.585	info	javascript.0 (17473) Start javascript script.js.common.test.sqlTest
                21:38:15.591	info	javascript.0 (17473) script.js.common.test.sqlTest: initial: -100
                21:38:15.592	info	javascript.0 (17473) script.js.common.test.sqlTest: undefined
                

                Zum anderen sagt zumindest der Editor als Mousover zum unterkringelten "await" vor "sendTo": 'await' has no effect on the type of this expression. (80007)

                1 Reply Last reply Reply Quote 0
                • S
                  spider_01 @haus-automatisierung last edited by

                  @haus-automatisierung

                  Oh, da warst du wesentlich schneller mit Input, als ich mit dem Ausprobieren! Werde mich mal eingehender damit beschäftigen (müssen)!

                  Vielen Dank für den Input!

                  haus-automatisierung 1 Reply Last reply Reply Quote 0
                  • haus-automatisierung
                    haus-automatisierung Developer Most Active @spider_01 last edited by

                    @spider_01 Du musst sendToAsync nutzen. Nicht mehr sendTo. Nur die erste liefert ein Promise zurück. sendTo arbeitet ja mit Callback.

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post

                    Support us

                    ioBroker
                    Community Adapters
                    Donate

                    601
                    Online

                    31.7k
                    Users

                    79.6k
                    Topics

                    1.3m
                    Posts

                    2
                    8
                    229
                    Loading More Posts
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes
                    Reply
                    • Reply as topic
                    Log in to reply
                    Community
                    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                    The ioBroker Community 2014-2023
                    logo