5. Interaktion mit dem Benutzer: Javascript im Browser

5.4 Callbacks: Javascripts Alternative zu Threads

Manchmal müssen mehrere Sachen gleichzeitig passieren. Wenn Sie zum Beispiel mit Javascript ein Spiel schreiben wollen, zum Beispiel Tetris, dann muss regelmäßig der Stein runterfallen; dabei soll aber die Seite weiterhin empfänglich für Ihren Input sein. Etwas relevanter für diesen Kurs vielleicht: wenn Sie eine Web-App schreiben, sollte ein Klick den save-Knopf die Daten zum Speichern an den Server schicken, sollte aber möglichst nicht die ganze Seite blockieren. Zum Beispiel wollen Sie, dass der User währenddessen weiter irgendwas machen / editieren / spielen kann.

In Java gibt wird diese Nebenläufigkeit mit der Klasse Thread implementiert. Speichern Sie AnnoyingThread.java, kompilieren und rufen Sie es auf.

Callbacks

Javascript hat keine expliziten Threads, sondern nutzt callbacks. Bauen wir unsere (leicht konstruierte) Problemstellung nach und nach auf. In der Datei 07-a-changeTableRows.html sehen Sie eine Tabelle und können per Knopfdruck die Hintergrundfarbe der Tabellenzeilen ändern. Der entscheidende Code ist

            <input type="submit" value="change color" onClick="changeColorOfNextTr()">

und changeColorOfNextTr() macht dann den Farbwechsel.

Auswelchem Grund auch immer will ich nun einen zeitverzögerten Farbwechsel machen; auf Knopfdruck soll nach einer Sekunde die Farbe wechseln. Allerdings soll während dieser Zeit die Seite weiterhin aufmerksam sein, d.h., Javascript soll weiter im Hintergrund laufen. Das Ergebnis sehen Sie in der Seite 07-b-changeTableRows. Während Sie noch auf die Reaktion auf den ersten Knopfdruck warten, können Sie den zweiten Knopf drücken, dessen Effekt unmittelbar eintritt. Die entscheidenden Code-Zeilen sind:

            <input type="submit" value="change color with delay"  onClick="delayChangeColorOfNextTr()">
            <input type="submit" value="change color immediately" onClick="changeColorOfNextTr()">

im HTML-Teil und dann im Javascript:

  function delayChangeColorOfNextTr() {
    setTimeout(changeColorOfNextTr, 1000);
  }

die bereits vorhandene Funktion setTimeout(callbackFunction, timeInMillisec) erwartet zwei Argumente: milliSec ist die Zeit (in Millisekunden) die gewartet werden soll; callbackFunction ist eine Funktion, die aufgerufen wird, wenn diese Zeit verstrichen ist. Sie müssen also eine Funktion als Argument übergeben. Ein anderes Anwendungsbeispiel ist, wenn Sie einen bestimmten Code alle X Millisekunden ausführen wollen. Hier ist ein Beispiel: 07-c-Ackermann.html.

Schauen wir uns ein einfacheres Beispiel, nämlich 07-d-display-time.html. Diese Seite gibt jede Sekunde die aktuelle Zeit an. Die entscheidenden Code-Zeilen sind im HTML-Text

        <button onclick="startShowDateInterval()">Show date and time</button>
und im Java-Script:
        setInterval(displayTimeAndDate, 1000);

Manchmal wollen Sie so ein Interval auch beenden (auch eventuell um es später wieder zu starten). Um dies zu tun, müssen Sie sich den Rückgabewert von setInterval merken:

        myInterval = setInterval(displayTimeAndDate, 1000);

Dann können Sie, z.B. wenn der User Pause drückt, mit dem Befehl clearInterval(myInterval) den Prozess beenden. Wenn Sie aus Java kommen, stellen Sie sich einfach vor, dass setInterval(callbackFunction, timeInMillisec) einen Thread erschafft und startet, der alle timeInMillsec Millisekunden die Funktion callbackFunction aufruft.

Übung Erstellen Sie eine Webseite mit einem Knopf start. Dies soll einen Prozess starten, der z.B. immer weiter Zufallszahlen ausdruckt. Irgendwas, Hauptsache, man kann das Ergebnis "beobachten". Es soll noch einen Knopf pause geben. Alternativ gestalten Sie den Knopf so, dass auf im start oder pause erscheint, je nachdem, in welchem Zustand er gerade ist.