Futures i async/await
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 76 z 110.
W rzeczywistych aplikacjach wiele operacji zajmuje czas — pobieranie danych z serwera, odczytywanie plików lub oczekiwanie na dane wejściowe od użytkownika. Dart obsługuje je za pomocą Future, który reprezentuje wartość dostępną w przyszłości.
Future przypomina obietnicę: „Podam ci wynik, gdy będzie gotowy”. Możesz utworzyć ją za pomocą Future.delayed(), aby zasymulować operację, która zajmuje trochę czasu:
Future<String> fetchUserName() {
return Future.delayed(
Duration(seconds: 1),
() => 'Alice',
);
}Aby pracować z wynikiem obiektu Future, użyj async i await. Oznacz swoją funkcję jako async, a następnie użyj await, aby wstrzymać wykonywanie do momentu zakończenia obiektu Future:
Future<void> main() async {
print('Fetching user...');
String name = await fetchUserName();
print('Hello, $name!');
}
Future<String> fetchUserName() {
return Future.delayed(
Duration(seconds: 1),
() => 'Alice',
);
}Bez await otrzymasz Future<String> zamiast właściwego ciągu znaków. Słowo kluczowe await rozpakowuje Future i zwraca zawartą w nim wartość. Pamiętaj, że każda funkcja używająca await musi być oznaczona jako async i automatycznie zwraca Future.
Możesz też zwracać wartości bezpośrednio z funkcji asynchronicznych — Dart automatycznie opakowuje je w Future:
Future<int> calculateTotal() async {
var a = await fetchNumber();
var b = await fetchNumber();
return a + b; // Automatycznie opakowane w Future<int>
}Wyzwanie
ŁatwyZbudujmy usługę pogodową, która symuluje pobieranie danych pogodowych z różnych miast! Poćwiczysz korzystanie z Future, async i await, aby obsługiwać operacje, których ukończenie wymaga czasu.
Podzielisz swój kod na dwa pliki:
weather_service.dart: Utwórz klasęWeatherService, która symuluje pobieranie informacji o pogodzie. Twoja klasa powinna zawierać:- Metodę
fetchTemperature(String city), która zwracaFuture<int>. UżyjFuture.delayed()z czasem trwania wynoszącym 100 milisekund, aby zasymulować opóźnienie sieciowe. Metoda powinna zwracać temperaturę zależną od nazwy miasta: długość nazwy miasta pomnożoną przez 3. - Metodę
fetchCondition(String city), która zwracaFuture<String>. UżyjFuture.delayed()z opóźnieniem wynoszącym 100 milisekund. Zwróć'Sunny', jeśli nazwa miasta ma parzystą liczbę znaków, a w przeciwnym razie zwróć'Cloudy'. - Metodę asynchroniczną
getFullReport(String city), która zwracaFuture<String>. Ta metoda powinna zaczekać na zakończenie zarównofetchTemperature, jak ifetchCondition, a następnie zwrócić sformatowany ciąg znaków:'[city]: [temperature]C, [condition]'
- Metodę
main.dart: Zaimportuj swoją usługę pogodową i pokaż, jak działają operacje asynchroniczne. Twoja główna funkcja powinna być asynchroniczna i:- Utworzyć instancję
WeatherService - Wypisać
Fetching weather data... - Poczekać na pełny raport dla
'Paris'i go wypisać - Poczekać na pełny raport dla
'Tokyo'i go wypisać - Poczekać na pełny raport dla
'London'i go wypisać - Wypisać
Done!
- Utworzyć instancję
Zauważ, że każde wywołanie getFullReport czeka na pobranie zarówno temperatury, jak i warunków pogodowych, zanim zwróci połączony wynik. Słowo kluczowe await wstrzymuje wykonywanie programu do momentu zakończenia każdego obiektu Future!
Oczekiwany wynik:
Fetching weather data...
Paris: 15C, Cloudy
Tokyo: 15C, Cloudy
London: 18C, Sunny
Done!Spróbuj swoich sił
import 'weather_service.dart';
Future<void> main() async {
// TODO: Utwórz instancję WeatherService
// TODO: Wypisz 'Fetching weather data...'
// TODO: Poczekaj na pełny raport dla 'Paris' i go wypisz
// TODO: Poczekaj na pełny raport dla 'Tokyo' i go wypisz
// TODO: Poczekaj na pełny raport dla 'London' i go wypisz
// TODO: Wypisz 'Done!'
}
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