Asynchron programmieren mit Dart
Streams in Dart |
Nun ist das schon eine Weile her und ich denke es kann nicht schaden das Thema noch einmal aufzugreifen.
Bevor wir uns Details anschauen noch einmal eine Auffrischung der Basis !
Synchron versus Asynchron
Wenn wir in Dart ein Programm schreiben, wird es abgearbeitet bis es beendet wird. Das heisst Zeile für Zeile unseres Codes wird ausgeführt, in der von uns bestimmten Reihenfolge. Das Programmende können wir als Programmierer bestimmen, oder der Benutzer beendet das Programm mit Mechanismen die außerhalb des Codes liegen, dem Taskmanager in Windows als Beispiel.
Die nächste Zeile im Code kann jeweils erst dann ausgeführt werden, wenn die aktuelle verarbeitet ist und etwaige Resultate dieser Zeile vorliegen.
Der Vorteil dieser synchronen Abarbeitung des Codes ist, das wir immer mit konkreten Ergebnissen arbeiten. Der Nachteil ist, das unser Programm unter Umständen auf das Ergebnis einer Operation warten muss, da sie mehr Zeit in Anspruch nimmt. Warten auf ein Ergebnis heisst aber auch, das unser Programm blockiert ist, solange dieses nicht vorliegt.
Der Vorteil dieser synchronen Abarbeitung des Codes ist, das wir immer mit konkreten Ergebnissen arbeiten. Der Nachteil ist, das unser Programm unter Umständen auf das Ergebnis einer Operation warten muss, da sie mehr Zeit in Anspruch nimmt. Warten auf ein Ergebnis heisst aber auch, das unser Programm blockiert ist, solange dieses nicht vorliegt.
Die Lösung für diese Problematik ist die asynchrone Programmierung. Sie wartet nicht auf das Ergebnis, sondern stellt sicher das, sobald das Ergebnis da ist, korrekt damit umgegangen wird. Inzwischen aber kann unser Code weiter abgearbeitet werden, ohne blockiert zu sein. Nun gehen wir ins Detail.
Future
Dart stellt uns zur Implementierung von asynchronem Code Hilfsmittel zur Verfügung. Das einte ist die Future Klasse. Der erste große Unterschied zu Stream ist, das ein Future besser für Einzelfälle eingesetzt werden kann. Hier ein Beispiel:
void main(){ var zukunft = Future.value(14); print(zukunft); }
Der folgende Versuch das Ergebnis mit einer print(...) Funktion auszudrucken wird scheitern !
Warum ?: Die print Funktion wird ausgeführt, obwohl das Ergebnis des Futures noch nicht vorliegt ! Im DartPad erhalten wir als Ergebnis: Instance of '_Future<int>'
Sie sehen die Problematik ?Natürlich gibt es Abhilfe für dieses Problem. Die erste Lösung:
void main() { var zukunft = Future.value(14).then((ergebnis) => print(ergebnis)); }
Dabei ist der Inhalt von .then(...) wiederum eine Funktion, diese kann in der Fat Arrow Schreibweise wie oben implementiert sein, oder in der Langform (...){...}. Um die zeitliche Abfolge zu verstehen testen Sie diesen Code im DartPad:
void main() { var zukunft = Future.value(14).then((ergebnis) => print(ergebnis)); print('Mein Ausdruck'); print(zukunft); }
Jetzt ist es aber durchaus möglich, das Sie ein Future als Ergebnis bekommen, auf das Sie warten möchten oder müssen. Auch hier hat Dart eine Lösung:
void main() async { int zukunft; zukunft = await Future.value(14); print('Mein Ausdruck'); print(zukunft); }
Im Code oben wird korrekt zuerst "Mein Ausdruck" in die Konsole gedruckt, dann die 14 . Was passiert wenn wir den asynchronen Code in eine eigene Funktion packen ? :
void meineZukunft(zukunft)async{ int zahl1 = zukunft; zukunft = await Future.value(zahl1); print(zukunft); } void main(){ int zahl = 14; meineZukunft(zahl); print('Mein Text'); }
Wenn Dart den Code verarbeitet, wird die Funktion aufgerufen, aber nicht Ihre Beendigung abgewartet.
Ich denke das Prinzip hinter Future sollte klar sein. Vertiefende Informationen zur Future Klasse entnehmen Sie wie immer der hervorragenden Dokumentation von Dart. Bis bald.
Kommentare
Kommentar veröffentlichen