Menu
Coddy logo textTech

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.

challenge icon

Wyzwanie

Łatwy

Zbudujmy 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 _holdings jako 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 zwraca Future<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 zwraca Future<double>. Powinna oczekiwać na wynik fetchPrice dla 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 zwraca Future<double>. Powinna obliczyć łączną wartość wszystkich posiadanych akcji, oczekując na wynik getStockValue dla każdej z nich i sumując otrzymane wartości
    • Asynchroniczną metodę generateReport(), która zwraca Future<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 jako Total: $[totalValue] (również z dokładnością do 1 miejsca po przecinku)
  • 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: AAPL w liczbie 10, GOOGL w liczbie 5, MSFT w liczbie 8
    • Wyświetl Fetching portfolio data...
    • Poczekaj na wynik generateReport() i wyświetl go

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.5

Spró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
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Dart online