header small transparent
  • STARTSEITE
  • PROJEKTE
    • Referenzen
  • LEISTUNGEN
  • SCHWERPUNKT
  • ÜBER UNS
    • UNSER ANGEBOT
    • UNSERE UNTERNEHMENSLEITUNG
  • Blog @ DEVBRAIN
  • KARRIERE
  • KONTAKT

Angular/Typescript Async/Await

2. May 2019Björn FrohbergAngular2, Coding, TypeScript, UncategorizedNo Comments

Überblick

Service Module in Angular/Typescript sind sehr gut, um Funktionen sauber vom übrigen Code zu trennen.

Aber Achtung! Beim Verwenden der Services ist ein synchroner Abruf nicht immer ratsam. Aufwendige Funktionen benötigen mehr Zeit, wodurch der Anwender auf die Rückmeldung des Service warten muss. Dies lässt sich umgehen, indem ein Service zu einem Observable Service umgewandelt wird. Er bietet dann die Möglichkeit asynchron eine Aufgabe zu starten und über Callback-Funktionen das Ergebnis oder Fehler zurückzumelden. So bleibt die Applikation flüssig und der Anwender muss nicht warten.

Das Observable Pattern ist verständlich, dennoch es lässt sich noch einfacher formulieren. Die Funktionalität ist dabei die gleiche.

Dieses Beispiel simuliert eine Webseite mit verschiedenen Arten eine Reihe von Aktionen zu laden.

Dabei ist der 1. Parameter von subscribe der Callback, um das Ergebnis am Ende des Aufrufs zu verwenden. Der zweite Parameter von subscribe ist der Callback für einen Fehlertext, den der Serviceaufruf provoziert hat. Der dritte Parameter (Handler) wird ganz zuletzt aufgerufen. Er ist optional.

Hier der Aufruf der Funktionaliät getAllReaders():


Die Service Implementierung in Typescript ist in dem nächsten Service zu sehen:

Dies ist das Beispiel in der Async/Await Variante. Der Catch-Block kann auch als Promise catch()-Aufruf genutzt werden:


Ein Miniprojekt zeigt die Unterschiede auf

Diese Single-Page Applikation soll als Reaktion auf einen Klick eine Reihe von Aktionen von einem Service abrufen und zwar auf Art und Weise, wie es der Anwender möchte

  • Synchron
  • Asynchron ohne await
  • Asynchron mit await

Jede Aktion wird per ng-for
geladen, sobald sich die Liste ändert. Jede Aktion nach einander.

Struktur

Projektstruktur per NodeJs Package-Manager (init)

app.component.html

Der Aufruf der Funktion onRunRequest() beinhaltet 3 Abschnitte, die zu 3 verschiedenen Aktionen führen, abhängig von den aktivierten CheckBoxen.

Diese Aktionen sind

  • Synced
  • Async + No Await
  • Async + Await

app.component.ts

action.service.ts

synchroner Einzelabruf:

Asynchroner Einzelabruf

action.service.ts

code getNextActionPromise

Initiale Webseite

Um die Webseite in betrieb zu nehmen muss ng serve in der Konsole aufgerufen werden. Es kompiliert die Application und startet einen Dienst, der Standardgemäß Port 4200 verwendet. (http://localhost:4200)

checkbox “asynchron” and request button, hidden await checkbox

Zur Service-Klasse

Ein Service ist per @Injectable() annotiert. Die Service-Component-Klasse wird damit durch Dependency Injection gefunden. Zudem muss der Service in der app.module.ts eingetragen werden.

add service to providers

Zu den Unterschieden

1. Ergebnis des synchronisierten / sequentiellen Aufruf aller Aktionen

synched

Auffälligkeiten

Nach dem Klick auf „Request All Actions“ musste der Nutzer 8 x 300 ms warten. 2,4 Sekunden die der Nutzer vergeuden musste.

2. Ergebnis des asynchronen / parallelen Abruf aller Aktionen

async + no await

Auffälligkeiten

Nach dem Klick auf „Request All Actions“, war es zu jedem Moment möglich erneut „Request All Actions“ zu klicken und so die Abfrage erneut zu starten. Die Schaltflächen (Aktionen) sind nacheinander aufgelistet worden. Auf hier dauerte der Aufbau 8 x 300 ms (2,4 sek.), aber der Nutzer konnte alle Komponenten der Seite weiterverwenden. Das bedeutet auch, dass er die Seite scrollen konnte. Das Zeichnen der Webseite wurde niemals unterbrochen.

Im Konsolen-Log auf der rechten Seite sieht man, dass die Abfrage bereits beendet ist, noch vor dem Erhalt der ersten Aktion vom Service, siehe die rote Markierung.

3. Ergebnis des asynchronen / parallelen Abrufs aller Aktionen, jedoch mit der Verwendung von await am Service-Aufruf

async + await

Auffälligkeiten

Wie erwartet, wurde auch hier nicht auf das volle Ergebnis gewartet. Jedoch sorgte der Serviceabruf mit vorangestellten await dafür, dass der erste Abruf der ersten Aktion abgewartet wird, bevor die Klick-Methode durchlaufen war, siehe rote Markierung.

Fehler

Jeder asynchrone Klick hat zur Folge, dass die gelisteten Elemente erneut befüllt werden, wodurch ein bereits abgeschickter asynchroner Aufruf ggf. andere Folgeelemente lädt.

Als Schreibtischtest

  1. Klick, dann Liste Leeren, dann Senden von index 0, dann Abwarten, dann Element 0 wird gezeigt
  2. (Rekursion), dann Senden von index 1, dann Abwarten, dann Element 1 wird gezeigt, dann (später)
  3. Klick, dann Liste Leeren, dann Senden von index 0, dann Abwarten, dann Element 2 wird gezeigt (von Rekursion erhalten), dann Element 0 wird gezeigt
  4. (Rekursion), dann Senden von index 1, dann Abwarten, dann Element 1 wird gezeigt, usw.

Ergebnis

Klick, dann Element 0, Element 1
Klick, dann Element 2, Element 0, Element 1 …

Die Lösung

Das Ergebnis nicht verwenden, wenn ein neuer Klick erfolgt ist.

Meine Lösung ist es, beim Klick die aktuelle ID durch eine zufällige neue UUID zu ersetzen. Jedem Abruf wird die aktuelle ID mitgegeben und im Ergebnis von NextAction wird die verwendet UUID, die aktiv war beim Aufruf im Ergebnis mitgegeben, so dass bei der Auswertung die gelieferte UUID mit der aktiven UUID verglichen werden kann. Nur, wenn die aktive UUID mit der gelieferten UUID übereinstimmt, wird die Aktionsliste mit dem Ergebnis erweitert und Folge-Aktionen werden abgerufen.

Ergebnis

Klick ID=#1, dann Element 0 (ID=#1), Element 1 (ID=#1)
Klick ID=#2, dann (Element 2 (ID=#1) ignoriert, denn #2 ungleich #1), Element 0 (ID=#2), Element 1 (ID=#2) …

Tags: angular, Async, Await, Clean Code, Dependency Injection, Feedback, Observable, Service, Typescript, UX
Björn Frohberg
Hallo, ich bin Björn, gelernter Fachinformatiker für Anwendungsentwicklung und IT-Consultant, sowie Verwaltungsfachangestellter für Kommunalverwaltung. Ich entwickle Software bereits seit meines 1. Computers 1997. Angefangen mit QBasic und VBA entschied ich mich dann dazu mit C++ weiter zu machen, bin allerdings danach bei C# und Java angelangt. Ich bin zertifiziert als Microsoft Office Expert und zähle auch Android und Unity3D C# Spieleentwicklung zu meinen Fähigkeiten. #.Net;#java;#C#;#MySql;#Android;#Unity3D;#IntelliJ;#VisualStudio;#Spring;#SpringBoot;#Jackson;#Json;#Xml;#REST;#Angular;#Typescript;#Office;#Word;#Excel;#AI;'NeuralNetwork;#Photoshop;#Adobe Premiere;#Dependency Injection;#JUnit;#Mockito;#Log4J
Previous post Wie lege ich mit einem Greenfield Angular2 Projekt richtig los? Next post Java SpringBootApplication Rest-Controller + Typescript

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Deliberate Programming
  • Cross-platform code-sharing in Vue.js
  • Unit Testing in Vue.js
  • All you need to know about Xamarin
  • Hibernate-Anbindung an einen Rest-Service (Java)

Recent Comments

    Archives

    • July 2019
    • June 2019
    • May 2019
    • April 2017
    • January 2017
    Burckhardtstraße 1 - 30163 Hannover
    +49 (0) 511 940 85 245 | +49 (0) 176 234 477 67
    info@devbrain-it.de

    Informationen

    kununu
    • Impressum
    • Datenschutz
    © 2020 DEVBRAIN IT SOLUTIONS GmbH

    Kontakt

    Email
    Facebook
    YouTube