twb: setInterval()

Liebe alle - ich habe einen Knoten in der Leitung, wie wir Schweizer sagen. Ich bin dabei, eine mathematisch-biologische Simulation zu schreiben ("The Game of Life"), die das Entstehen und Verschwinden von Organismen simuliert. Das Ding steht hier: Game of Life.

Per Klick lassen sich Grundparameter wie die Simulationsgeschwindigkeit oder die (zufällige) Populationsdichte einstellen; ein Klick auf "Start" startet die Simulation. Die zugehörige Javascript-Funktion lautet

function step()
{
setInterval('calc()',speed[0]);
}

wobei calc() die Berechnungsfunktion ist und die Arrayposition 0 von speed die gewählte Geschwindigkeit. Meine Absicht war nun, die Funktion auch wieder stoppen zu können. Mein Code war:

function step(a)
{
if (a==1) setInterval('calc()',speed[0]);
else clearInterval();
}

Dabei hätte "Start" die Funktion mittels step(1) gestartet; "Stop" hätte sie mittels step(0) wieder stoppen sollen. Funktioniert nicht die Spur. Hilft mir als Nichtprogrammierer jemand schonend auf die Sprünge? Mit riesigem Dank, twb

  1. Dabei hätte "Start" die Funktion mittels step(1) gestartet; "Stop" hätte sie mittels step(0) wieder stoppen sollen. Funktioniert nicht die Spur. Hilft mir als Nichtprogrammierer jemand schonend auf die Sprünge? Mit riesigem Dank, twb

    Schau dir mal das Beispiel zu setInterval auf selfhtml an

    Struppi.

    1. Schau dir mal das Beispiel zu setInterval auf selfhtml an

      Hatte ich bereits, aber ich war über den prinzipiellen Unterschied gestolpert - das SelfHTML-Beispiel stoppt nach i>=100 (Zähler), ich suchte nach einer Abbruchmöglichkeit durch den User. Aber Du hattest natürlich recht - ich hab' mein Game of Life erfolgreich so angepasst (Start übergibt step(1); Stop dagegen calc(0)):

      function step(a)
      {
      if (a==1) halt=window.setInterval('calc()',speed[0]);
      }

      function calc(a)
      {
      if (a==0)
      {
      window.clearInterval(halt);
      }
      [...]
      }

      Mein Problem nun: Nur wenn ich die Schrittzeit auf eine halbe oder ganze Sekunde erhöhe (Klicks auf Speed), hat ein Klick auf Stop eine Wirkung. Bei Schrittzeiten <500ms läuft das Skript munter weiter und lässt sich nur noch per F5 unterbrechen. Ist das zu ändern?

      1. Mein Problem nun: Nur wenn ich die Schrittzeit auf eine halbe oder ganze Sekunde erhöhe (Klicks auf Speed), hat ein Klick auf Stop eine Wirkung. Bei Schrittzeiten <500ms läuft das Skript munter weiter und lässt sich nur noch per F5 unterbrechen. Ist das zu ändern?

        Das läßt sich nur damit erklären, dass du sehr viele Intervale startest anstatt einen, d.h. deine Ablauflogik ist vermutlch falsch.

        Struppi.

        1. Das läßt sich nur damit erklären, dass du sehr viele Intervale startest anstatt einen, d.h. deine Ablauflogik ist vermutlch falsch.

          Nein. Ich starte ein einziges setInterval, das ich dann per User-Request auch wieder stoppen kann.

          Der Grund für das geschilderte Verhalten liegt vermutlich einfach darin, dass wenn die Ausführungszeit der per setInterval gestarteten Funktion die angegebene Intervallzeit übersteigt, eine weitere Funktion (Stopp) nicht ausgeführt wird. Bei komplexen Funktionen wie im Game of Life bei gleichzeitig sehr kurzer Intervallzeit von 10ms ist das durchaus möglich. Wenn dagegen die Intervallzeit länger ist als die Ausführungszeit der Funktion, funktioniert alles tadellos.

          Ich habe also die Simulationszeiten etwas verlängert. Trotzdem danke!

          1. Der Grund für das geschilderte Verhalten liegt vermutlich einfach darin, dass wenn die Ausführungszeit der per setInterval gestarteten Funktion die angegebene Intervallzeit übersteigt, eine weitere Funktion (Stopp) nicht ausgeführt wird.

            Nein, das kann kein Grund sein. Du machst irgendetwas falsch, ich kann es aber in deinem Code nicht erkennen was. Aber du hast auch wieder so programmiert das es möglichst schwer ist Fehler zu finden :-(

            Ich habe also die Simulationszeiten etwas verlängert. Trotzdem danke!

            Also ich kann das Ding nicht immer stoppen.

            Struppi.

            1. Nein, das kann kein Grund sein. Du machst irgendetwas falsch, ich kann es aber in deinem Code nicht erkennen was. Aber du hast auch wieder so programmiert das es möglichst schwer ist Fehler zu finden :-(

              Ich geb's zu und kann's nicht besser. Und hoffe auf einen glücklichen Einfall - vielleicht finde ich gelegentlich doch noch heraus, woran mein js-Code krankt. Trotzdem merci! Herzlich, twb

              1. Ich geb's zu und kann's nicht besser. Und hoffe auf einen glücklichen Einfall - vielleicht finde ich gelegentlich doch noch heraus, woran mein js-Code krankt.

                Naja, in erster Linie am Stil und an den globalen Variabeln (du kannst mir nicht erzählen, dass du var nicht kennst)

                Du könntest u.U. den Fehler finden wenn du versuchst der Geschichte auf den Grund zu gehen. Was passiert denn? Der Interval wird nciht unterbrochen, das kann mehrere Gründe haben, einer ist, dass aus irgendeinem Grund ein der Timer halt nicht der Timer ist, der du denkst das es er wäre.

                Mein Ansatz wäre z.b. zu testen ob beim setzten des Interval evtl. halt schon läuft (dann würde der vorherige Interval nicht mehr stoppbar sein, da du die Variabel ja überschreibst).

                if ( a == 1 )  
                if(halt) alert('geht nicht! "halt" wurde schon gesetzt');  
                else halt=window.setInterval('calc()',speed[0]);  
                
                

                Struppi.

                1. Mein Ansatz wäre z.b. zu testen ob beim setzten des Interval evtl. halt schon läuft (dann würde der vorherige Interval nicht mehr stoppbar sein, da du die Variabel ja überschreibst).

                  Das ist richtig. Hab' ich auch getestet - aber nein: Ein zweites Interval läuft nicht, und die Variable halt existiert auch nur einmal. Das war also nicht die Ursache. Den zuvielen globalen Variablen rücke ich ebenfalls zuleibe, aber auch das scheint mein Skript nicht wesentlich zu beschleunigen. Merci einewäg! (=schweizerdeutsch für: Danke trotzdem!)

              2. Hallo,

                Vielleicht finde ich gelegentlich doch noch heraus, woran mein js-Code krankt.

                Wie Struppi schon bemerkte, ist der Code nicht besonders elegant, vor allem auch unübersichtlich. Wenn man ihn besser strukturiert, sieht calc() z.B. so aus:

                  
                function calc(a)  
                {  
                  neighbor=[-41,-40,-39,-1,1,39,40,41];  
                  numb=new Array();  
                  if (a==0)            // Besser: if(a){...}  
                  {  
                    message="Stopped.";  
                    menu.reverse();  
                    window.clearInterval(halt);  
                  }  
                  else message="Running...";  
                  
                  // Folgendes wird auch dann ausgeführt, wenn a==0 gilt (ist das Absicht?):  
                  
                  for (i=0;i<1600;i++)  
                  {  
                    num=0;  
                    for (j=0;j<8;j++) if (cell[i+neighbor[j]]==b) num++;  
                    numb.push(num);  
                  }  
                  
                  for (i=0;i<1600;i++)  
                  {  
                    if (cell[i]!=b) if (numb[i]==3) cell[i]=b;  
                    if (cell[i]==b) if (numb[i]<2||numb[i]>3) cell[i]="<td id=\"white\" onclick=\"draw("+i+")\"><\/td>";  
                  }  
                  show();  
                }
                

                Gruß, Don P

                1. // Folgendes wird auch dann ausgeführt, wenn a==0 gilt (ist das Absicht?):

                  Richtig bemerkt - nein: Wenn a==0, müssen die nachfolgenden Schleifen nicht mehr ausgeführt werden. Hab' ich korrigiert. Danke!