Asynchroniczność w metodach klasy
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 80 z 110.
Skoro wiesz już, jak obsługiwać asynchroniczną inicjalizację za pomocą metod fabrykujących, przyjrzyjmy się asynchronicznym zwykłym metodom instancji. To proste — wystarczy dodać async do dowolnej metody i sprawić, by zwracała Future.
class WeatherService {
String _location;
WeatherService(this._location);
Future<String> fetchTemperature() async {
await Future.delayed(Duration(seconds: 1));
return '22°C in $_location';
}
Future<void> updateLocation(String newLocation) async {
await Future.delayed(Duration(milliseconds: 500));
_location = newLocation;
print('Location updated to $_location');
}
}
Future<void> main() async {
var service = WeatherService('London');
var temp = await service.fetchTemperature();
print(temp);
await service.updateLocation('Paris');
}Metody asynchroniczne mogą uzyskiwać dostęp do zmiennych instancji i modyfikować je tak samo jak zwykłe metody. Kluczowa różnica polega na tym, że wywołujący muszą użyć await, aby odebrać wynik. Metody zwracające Future<void> nie zwracają wartości, ale nadal trzeba na nie poczekać, jeśli chcesz mieć pewność, że zakończą działanie, zanim przejdziesz dalej.
Możesz także łączyć wiele wywołań asynchronicznych w ramach metody lub wywoływać inne metody asynchroniczne z tej samej klasy:
Future<String> getFullReport() async {
var temp = await fetchTemperature();
var humidity = await fetchHumidity();
return '$temp, Humidity: $humidity';
}Ten wzorzec jest niezbędny w przypadku klas, które korzystają z zasobów zewnętrznych — API, baz danych lub wykonują operacje wymagające czasu.
Wyzwanie
ŁatwyZbudujmy narzędzie do śledzenia portfela akcji, które zarządza cenami akcji i oblicza wartość portfela za pomocą metod asynchronicznych! Utworzysz klasę symulującą pobieranie danych giełdowych w czasie rzeczywistym i łączącą wiele operacji asynchronicznych w celu generowania raportów.
Uporządkujesz kod w dwóch plikach:
portfolio.dart: Utwórz klasęStockPortfolio, która śledzi akcje i ich liczby. Klasa powinna zawierać:- Prywatną
Map<String, int>o nazwie_holdings, która przechowuje symbole akcji i liczbę posiadanych udziałów - Konstruktor, który inicjuje
_holdingsjako pustą mapę - Metodę
addStock(String symbol, int quantity), która dodaje lub aktualizuje posiadane akcje (nie jest asynchroniczna) - Asynchroniczną metodę
fetchPrice(String symbol), która zwracaFuture<double>. Zasymuluj opóźnienie wynoszące 50 milisekund, a następnie zwróć cenę obliczoną jako długość symbolu pomnożona przez 25.5 - Asynchroniczną metodę
getStockValue(String symbol), która zwracaFuture<double>. Powinna oczekiwać na wynikfetchPricedla danego symbolu, pomnożyć go przez liczbę posiadanych akcji i zwrócić łączną wartość. Jeśli symbolu nie ma w posiadanych akcjach, zwróć 0.0 - Asynchroniczną metodę
getTotalValue(), która zwracaFuture<double>. Powinna obliczyć łączną wartość wszystkich posiadanych akcji, oczekując na wynikgetStockValuedla każdej z nich i sumując otrzymane wartości - Asynchroniczną metodę
generateReport(), która zwracaFuture<String>. Powinna utworzyć raport przedstawiający wartość każdej akcji oraz łączną wartość. Sformatuj każdy wiersz jako[symbol]: $[value](wartość z dokładnością do 1 miejsca po przecinku), a ostatni wiersz jakoTotal: $[totalValue](również z dokładnością do 1 miejsca po przecinku)
- Prywatną
main.dart: Zaimportuj plik portfolio i pokaż, jak metody asynchroniczne współpracują ze sobą w obrębie klasy:- Utwórz instancję
StockPortfolio - Dodaj następujące akcje:
AAPLw liczbie 10,GOOGLw liczbie 5,MSFTw liczbie 8 - Wyświetl
Fetching portfolio data... - Poczekaj na wynik
generateReport()i wyświetl go
- Utwórz instancję
Zwróć uwagę, jak generateReport() wywołuje inne metody asynchroniczne w obrębie tej samej klasy i jak każda metoda bazuje na poprzednich. Użyj toStringAsFixed(1), aby sformatować wartości dziesiętne!
Oczekiwany wynik:
Fetching portfolio data...
AAPL: $1020.0
GOOGL: $637.5
MSFT: $816.0
Total: $2473.5Spróbuj swoich sił
import 'portfolio.dart';
void main() async {
// TODO: Utwórz instancję StockPortfolio
// TODO: Dodaj posiadane akcje:
// - AAPL: 10 akcji
// - GOOGL: 5 akcji
// - MSFT: 8 akcji
// TODO: Wypisz "Fetching portfolio data..."
// TODO: Poczekaj na wynik generateReport() i go wypisz
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy OOP
Pliki zewnętrzneBiblioteki i importyWprowadzenie do OOPKlasy a obiektySłowo kluczowe thisMetodyZmienne instancjiPodstawy konstruktorówPowtórka – prosty kalkulator4Bezpieczeństwo wartości null
Wprowadzenie do bezpieczeństwa wartości nullTypy dopuszczające null i niedopuszczające nullOperatory ? i !Słowo kluczowe late a bezpieczeństwo wartości nullOperatory uwzględniające nullBezpieczeństwo wartości null w klasachPodsumowanie — system profili użytkowników7Klasy abstrakcyjne i interfejsy
Klasy abstrakcyjneMetody abstrakcyjneInterfejsy w DartInterfejsy niejawneImplementowanie a rozszerzanieWiele interfejsówPowtórka — kalkulator kształtów10Kolekcje i typy generyczne
Przegląd List, Set i MapKolekcje bezpieczne typowoKlasy generyczneMetody generyczneOgraniczenia typów generycznychIterable i IteratorPowtórka — generyczne przechowywanie danych13Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieMetody rozszerzająceKlasy wywoływalneKlasy zapieczętowane (Dart 3)Rekordy (Dart 3)Wzorce i dopasowywanie (3.0)Typy wyliczeniowe z metodami16Projekt: Zarządzanie biblioteką
Omówienie projektuKlasy książek i użytkowników2Konstruktory w Dart
Konstruktor domyślnyKonstruktory nazwaneListy inicjalizująceKonstruktory stałeKonstruktory fabryczneKonstruktory przekierowującePodsumowanie — budowanie kształtów5Hermetyzacja
Elementy publiczne a prywatneKonwencja prefiksu _Prywatność na poziomie bibliotekiGettery i settery — szczegółowoUkrywanie informacjiPodsumowanie — dane uczniów8Domieszki
Wprowadzenie do domieszekTworzenie domieszekKorzystanie z wielu domieszekSłowo kluczowe on w domieszkachDomieszka a dziedziczenieDomieszka a interfejsPodsumowanie – system zwierząt11Metody specjalne
Nadpisanie toString()Nadpisanie hashCode i ==Interfejs ComparableMetoda call()Nadpisanie noSuchMethodPodsumowanie — własna kolekcja14Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec Strategy3Właściwości klas
Elementy instancji a elementy statycznePola final i constZmienne inicjalizowane z opóźnieniemMetody i pola statyczneGettery i setteryPowtórzenie – menedżer kont bankowych6Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe superPrzesłanianie metodAdnotacja @overrideSłowo kluczowe final dla klasKonstruktory i dziedziczeniePowtórzenie – hierarchia pracowników9Polimorfizm
Podstawy polimorfizmuPolimorfizm za pomocą interfejsówSprawdzanie typu w czasie działaniaOperatory is i asSłowo kluczowe covariantPodsumowanie — procesor płatności12Asynchroniczne OOP
Futures i async/awaitPodstawy strumieniKontrolery strumieniKonstruktory asynchroniczneAsynchroniczność w metodach klasyPodsumowanie — pobieranie danychPoćwicz samodzielnie: Kompilator Dart online