Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

JavaScript: Asynchrone Programmierung

Callback Hell

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Callback Hell definiert den Zustand der JavaScript-Programmiersprache, solange man sich nicht mit besonderen Konstrukten behilft.

Transkript

Im Laufe des folgenden Videos, begeben wir uns buchstäblich in die Hölle, die sogenannte Callback Hell. Ein nur allzu bekanntes Problem unter JavaScript Entwicklern. Ich zeige Ihnen nun also was genau ich mit Callback Hell meine, und wo die Gefahren dahinter liegen. Innerhalb meines JavaScript Projektes, beginne ich dafür mit dem Anlegen einer neuen JavaScript Datei. Ich nenne diese: 01_Callback_Hell.js. Fangen wir also beim Grundbegriff an: Der Callback. Die Funktion setTimeout, die uns standardmäßig von JavaScript zur Verfügung gestellt wird, erlaubt es uns, eine bestimmte Aktion in der Zukunft auszuführen. In diesem Fall möchte ich also, dass nach 1000 Millisekunden, auf die Konsole, der Text Hello ausgegeben wird. Wenn ich nun einen synchronen Programmfluss hätte, und diese Instruktion einmal dupliziere, und hier nun World eingebe, wäre meine Erwartung, dass nun nacheinander, erste Sekunde Hello und dann zweite Sekunde World kommt. Allerdings passiert das Ganze gleichzeitig. Füge ich nun noch eine console.log Zeile zwischen beide Befehle, so wird diese Zeile als Allererstes ausgeführt, unabhängig von den beiden anderen. Der wesentliche Unterschied ist nun also, dass wir mit Hilfe der setTimeout Funktion den Kontrollfluss an NodeJS übergeben, indem wir eine Funktion als Parameter an setTimeout übertragen, die nach der bestimmten Zeit tatsächlich erst ausgeführt wird. Dieses Verhalten ist soweit nichts besonderes, bringt aber einige interessante Problemstellungen mit sich. Denn, was ist nun, wenn ich tatsächlich möchte, dass Hello und World nacheinander ausgeführt werden, und zwar im Abstand von jeweils einer Sekunde? Ich beginne also in dem Fall wieder mit Hello, muss aber sicherstellen, dass World dann erst eine Sekunde später ausgeführt wird. Und kopiere daher World in die Funktion von Hello. Zusätzlich kommentiere ich noch die oberen Befehle aus, und starte nun meine Anwendung. Tatsächlich war ich nun also in der Lage, beide Befehle Hello und World, jeweils eine Sekunde nacheinander auszuführen. Möchte ich diesen Prozess allerdings mehrfach reproduzieren, so wird meine Strecke bis zu meinem jeweiligen Befehl, immer tiefer mit sogenannten Callbacks strukturiert. In einer sehr leichten Ausprägung, sehen wir nun also hier schon bereits, die Prinzipien hinter Callback Hell. Natürlich gibt es auch Möglichkeiten das Ganze etwas schöner zu strukturieren. Beispielsweise könnte ich keine anonymen Funktionen verwenden. Ich definiere also eine Funktion Hello, die einen Callback entgegennimmt, und auch mit Hilfe der setTimeout Funktion, und einem Abstand von einer Sekunde, auf die Konsole zunächst einmal Hello schreibt. Das Ganze reproduziere ich nun noch für die Funktion World, und als nächstes rufe ich den übergebenden Callback auf. Nach dieser doch etwas flacheren Definition, kann ich durch einen einfachen Aufruf von Hello, World, meine Anwendung zum selben Verhalten wie vorher bringen. Das Ganze wirkt zwar zunächst einmal schöner, hat aber die fast gleichen Probleme, da der Kontrollfluss, wie die Dinge hier aufgerufen werden, nicht klar ersichtlich ist. Denn im schlimmsten Fall können hier Seiteneffekte auftreten. Als Beispiel kann ich nun eine Funktion definieren, mit der Bezeichnung Time1, die ein Objekt entgegennimmt. Mit Hilfe der setTimeout Funktion, kann ich nun dieses Objekt beeinflussen. Beispielsweise durch Objekt.Test = 1, ich nutze nun den Zufallsfaktor mit math.random, mal 100, für Millisekunden, dupliziere diese Funktion nun, und setze damit die Variable 2 auf das Objekt Test. Als nächstes definiere ich also nun ein Objekt, auf dem Test zunächst einmal auf 0 gesetzt ist. Um zu zeigen, dass ich hier nun Seiteneffekte habe, die ich unter Umständen nicht sehen kann, verwende ich den Aufruf von der Funktion Time1 und der Funktion Time2, auf meinem Objekt. Nach etwa zwei Sekunden, möchte ich nun also prüfen, was auf meiner Variable Test in dem Objekt steht. Im ersten Fall bekomme ich nun also eine 1. Obwohl die Funktion Time2 als zweites ausgeführt wurde. Das kann ich nun beliebig oft wiederholen, und werde unter Umständen, immer ein anderes Ergebnis erhalten. Während dieses Beispiel nun sehr einfach ist, zeigt es schon illustrativ, wie einfach es sein kann, ungewollte Nebeneffekte durch die Schachtelung, über solche Funktionsaufrufe zu erreichen. Also auch das ist nicht der ideale Ansatz, um mit dem Problem Callbacks umzugehen. Zu guter Letzt, will ich ein praktisches Beispiel von Callback Hell zeigen. Indem ich einen Zugriff auf das Dateisystem mache. Ich importiere daher zunächst, mit Hilfe der Funktion require, die NodeJS Standardbibliothek file-system. Um hier Support von IntelliJ IDEA zu bekommen, kann ich die NodeJS code assistance aktivieren. Ich importiere nun also das Paket fs und das Paket path. Ich könnte nun also in meinem aktuellen Ordner, mit Hilfe der Funktion fs.readdir, mit Hilfe von dirname, also dem aktuellen Ordner, in dem die Datei ausgeführt wird, mir eine Liste aller Dateien geben lassen, mit Hilfe des Callbacks, der als erstes Argument, in diesem Fall nun, eine Fehlervariable entgegennimmt, und als zweites Argument, die Liste der Dateien in meinem Ordner. Da ich als Programmierer darauf achten sollte, immer mit Fehlern umzugehen, muss ich nun also berücksichtigen, dass es einen Fehler geben kann. Wenn das der Fall ist, möchte ich diesen auf die Konsole ausgeben, und die Funktion verlassen. Alternativ, statt sie zu verlassen, kann ich auch einfach mit Hilfe von else, weiter in die Tiefe gehen, und nun, beispielsweise für jede Datei, die ich bekommen habe, die Größe abfragen. Ich nutze hier also die Iterierfunktion, die, falls Sie sich wundern, nur im aktuellen JavaScript Standard existiert. Als nächstes gebe ich noch auf die Konsole den Namen der Datei aus, und mache nun einen weiteren Call auf die fs API, mit Hilfe von fs.lstat, nun relativ wieder zum Pfad, mit dem Pfadseparierer, und dem jeweiligen Dateinamen, bekomme ich nun wieder einen Callback, der selbstverständlich auch einen Fehler enthalten kann, das bedeutet, ich prüfe natürlich, ob ein Fehler vorliegt, und andernfalls, kann ich dann auf die Konsole die Größe der Datei ausgeben, mit Hilfe von res.size. Nicht nur, dass mein Code sehr unübersichtlich ist, hier werden mir auch noch einige andere Probleme meiner Callback Wüste bekannt. Beispielsweise, dass ich nun die Zuordnungen von den Dateigrößen, nicht mehr sauber zu den Dateien zuordnen kann. Dafür müsste ich die Variable file entsprechend hoisten, also in den Scope der unteren Funktion ziehen, und dort weiterverarbeiten. Das kann je nach Tiefe immer komplizierter und immer unübersichtlicher werden. Es sollte nun klar sein, dass Callback Hell, wirklich die absolute Hölle für JavaScript Entwickler ist. Letztendlich definiert sich Callback Hell also dadurch, dass Funktionen, Funktionen als Parameter nehmen und dadurch immer tiefer geschachtelt werden. Sie haben nun zahlreiche Gefahren gesehen, dazu gehören zum Einen das Variablen-Hoisting, also das άberschreiben oder in den Scope ziehen von Variablen, die nicht zur eigenen Funktion gehören, die Probleme mit der άbersichtlichkeit, um noch sinnvoll über den Code sprechen zu können, als auch die Beurteilung des Ablaufs, wie er sich aus der Funktion ergeben kann. Außerdem habe ich Ihnen gezeigt, wie anonyme Funktionen, als auch benannte Funktionen, trotz allem unerwünschte Nebenbedingungen mit sich bringen können, und daher auch benannte Funktionen keinen tatsächlichen Vorteil darstellen.

JavaScript: Asynchrone Programmierung

Lernen Sie Lösungen für die komplexe Anwendungsentwicklung kennen, um zeitaufwändige Ressourcenzugriife im Code zu vermeiden.

2 Std. 30 min (19 Videos)
Derzeit sind keine Feedbacks vorhanden...
 
Software:
Exklusiv für Abo-Kunden
Erscheinungsdatum:22.08.2016

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!