Geschrieben von

JavaScript: Callback-Funktionen

WebDev

Wenn du dich mit Funktionen in JavaScript auseinandergesetzt hast, dann stößt du schnell auf das Thema Callbacks oder Callback-Funktionen. Diese sind ein zentraler Bestandteil bei der asynchronen Programmierung in JavaScript. Was das genau bedeutet erfährst du in diesem Artikel.

Hintergrund

Funktionen sind in JavaScript auch gleichzeitig Objekte. Da wir Objekte in Funktionen als Parameter übergeben können, ist es auch möglich, Funktionen als Parameter in anderen Funktionen zu übergeben. Sehen wir uns folgenden Code an:

function print(callback) {
  callback();
};

Hier sehen wir, dass eine Funktion als Parameter übergeben und innerhalb der Funktion “print” auch ausgeführt wird.

Was sind Callback-Funktionen?

Bei Callback-Funktionen (Rückruffunktionen) handelt es sich um Funktionen, die als Parameter in anderen Funktionen übergeben werden. Wozu sie gebraucht werden, lässt sich am besten an einem Beispiel zeigen. Gehen wir davon aus wir haben 3 Funktionen:

printOne();
 
printTwo();
 
printThree();

JavaScript führt den Code grundsätzlich sequentiell (bzw. synchron) von oben nach unten aus. Das heißt:

  • Zuerst wird printOne() ausgeführt
  • Dann folgt printTwo()
  • Und zum Schluss wird printThree() ausgeführt

Jetzt gibt es aber auch Gründe oder Fälle, wo eine Funktion erst nach einer anderen Funktion ausgeführt werden soll und nicht vorher. Bei einer sequentiellen Anordnung und Ausführung könnte man dieses Ziel nicht erreichen. Daher muss man asynchron programmieren. Man spricht dabei auch einfach von Async JavaScript. Genau hier kommen Callbacks ins Spiel.

Callback-Funktionen im Einsatz

Im JavaScript gibt es verschiedene Möglichkeiten, wie man eine Callback-Funktion einsetzen kann:

  • setTimeout
  • Event-Listener
  • Eigene Callbacks

setTimeout

Mit setTimeout sind wir in der Lage eine Funktion nach einer bestimmten Zeit ausführen zu lassen. Hier wird der Funktion setTimeout eine andere Funktion als Parameter übergeben. Das stellt eine Callback-Funktion dar. Beispiel:

let print = function() {
  console.log("Funktion wurde ausgeführt");
};
 
setTimeout(print, 2000);

Hier wird die Funktion print erst dann ausgeführt, nachdem etwas passiert ist (= 2 Sekunden warten). Das wäre ein klassisches Beispiel für eine Rückruffunktion. Man könnte nun die Funktion auch zum Zeitpunkt der Deklaration übergeben. Hier wäre dann eine anonyme Funktion im Spiel, was in diesem Fall auch ein gängiger Weg ist:

setTimeout(function() {
  console.log("Funktion wurde ausgeführt");
}, 2000);

Ein anderes Beispiel. Gehen wir davon aus, dass die ersten zwei Funktionen folgendes machen:

let printOne = function() {
  console.log("Hallo 1");
}
 
let printTwo = function() {
  console.log("Hallo 2");
}
 
printOne();
 
printTwo();

Was würde hier passieren? Die Funktionen werden sequentiell – also nacheinander – ausgeführt. Sprich, in der Console steht dann:

Hallo 1
Hallo 2

Jetzt setzen wir aber ein setTimeout() für die Funktion printOne():

let printOne = function() {
  console.log("Hallo 1");
}
 
let printTwo = function() {
  console.log("Hallo 2");
}
 
setTimeout(printOne, 2000);
 
printTwo();

Was passiert hier? Die Funktion printOne() wird erst nach 2 Sekunden ausgeführt. Der Code wird dennoch weiter sequentuell – also nacheinander – ausgeführt und verarbeitet. Das hat zur Folge:

  • Zunächst wird printOne() verarbeitet. Hier sieht aber JavaScript, dass diese Funktion erst nach 2 Sekunden ausgeführt werden soll. Das merkt sich JS und geht weiter.
  • Bei printTwo() sieht JavaScript keine setTimeout() und führt die Funktion sofort aus.
  • Jetzt, wenn 2 Sekunden verstrichen sind, wird printOne() ausgeführt.

In der Console sehen wir also:

Hallo 2
Hallo 1

Event-Listener

Ein weiterer typischer Callback in JavaScript sind Event-Listener. Hier wird eine Funktion so lange zurückgehalten, bis ein Event stattgefunden hat. Die Funktion wird dem Event-Listener übergeben, weshalb man auch hier von einer Rückruffunktion spricht. Kommen wir zu einem Beispiel. Gehen wir davon aus, wir möchten auf einen Button reagieren:

let button = document.querySelector("#btn");
 
button.addEventListener("click", function() {
  console.log("Button wurde geklickt.");
});

In diesem Fall ist der Callback die Funktion, die in die Konsole was schreibt. Die Funktion wird also erst dann ausgeführt, wenn der Button geklickt wurde.

Eigene Callbacks

Bisher haben wir 2 Funktionen, die uns JavaScript zur Verfügung stellt (setTimeout und Event-Listener) für das Aufrufen von Rückruffunktionen verwendet. Was aber wenn wir eigene Funktionen als Callback benutzen möchten? Dazu schauen wir uns die 3. Möglichkeit an.

Gehen wir wieder vom folgenden Code aus:

let printOne = function() {
  console.log("Hallo 1");
}
 
let printTwo = function() {
  console.log("Hallo 2");
}
 
printOne();
 
printTwo();

Dies würde in der Konsole folgendes ausgeben:

Hallo 1
Hallo 2

Was aber wenn printOne erst nachdem printTwo fertig ist, ausgeführt werden soll? Dazu müssen wir nur printTwo aufrufen und als Parameter printOne übergeben. Die printTwo-Funktion muss aber diesen Parameter entgegen nehmen können und innerhalb der Funktion auch ausführen. Heißt:

let printOne = function() {
  console.log("Hallo 1");
}
 
let printTwo = function(callback) {
  console.log("Hallo 2");
  callback();
}
 
printTwo(printOne);

In der Konsole sieht man dann folgende Ausgabe:

Hallo 2
Hallo 1