← Назад к вопросам
Что такое async, await и Future в Dart?
1.6 Junior🔥 252 комментариев
#Dart#Асинхронность
Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Async, Await и Future в Dart
Future — асинхронное значение
Future — это объект, который представляет будущее значение, которое может быть доступно со временем или вызвать ошибку:
// Future завершится одним из трёх состояний:
// 1. Успешно (resolved) с значением
// 2. Ошибка (rejected) с исключением
// 3. В ожидании (pending) — ещё не завершён
Future<String> fetchUserName() {
// Эта функция вернёт значение через 2 секунды
return Future.delayed(
Duration(seconds: 2),
() => "John Doe",
);
}
// Использование Future
final future = fetchUserName();
// future содержит обещание получить имя позже
Обработка Future с .then()
fetchUserName().then((name) {
print("User: $name");
}).catchError((error) {
print("Error: $error");
}).whenComplete(() {
print("Request finished");
});
// Цепочка операций
Future<int> getUserAge(String name) {
return Future.delayed(
Duration(seconds: 1),
() => 30,
);
}
fetchUserName()
.then((name) => getUserAge(name))
.then((age) => print("Age: $age"))
.catchError((error) => print("Error: $error"));
async и await — читаемый синтаксис
async/await — это синтаксический сахар для работы с Future, делающий код выглядеть синхронным:
// ❌ Без async/await (callback hell)
fetchUserName().then((name) {
getUserAge(name).then((age) {
getAddress(age).then((address) {
print("$name, $age, $address");
}).catchError((e) => print("Error: $e"));
}).catchError((e) => print("Error: $e"));
}).catchError((e) => print("Error: $e"));
// ✅ С async/await (читаемо)
Future<void> getUserInfo() async {
try {
final name = await fetchUserName();
final age = await getUserAge(name);
final address = await getAddress(age);
print("$name, $age, $address");
} catch (e) {
print("Error: $e");
}
}
// Вызов
await getUserInfo();
Как работает async?
// Функция с async автоматически возвращает Future
async void sayHello() async {
print("Hello"); // Выполнится синхронно
await Future.delayed(Duration(seconds: 1));
print("World"); // Выполнится через 1 секунду
}
// Это эквивалентно:
Future<void> sayHello() {
print("Hello");
return Future.delayed(Duration(seconds: 1))
.then((_) => print("World"));
}
// Вызов async функции
await sayHello(); // Ждёт завершения
sayHello(); // Не ждёт, просто запускает
Future — примеры из реальной жизни
// HTTP запрос
Future<User> fetchUser(int id) async {
final response = await http.get(
Uri.parse("https://api.example.com/users/$id"),
);
if (response.statusCode == 200) {
return User.fromJson(jsonDecode(response.body));
} else {
throw Exception("Failed to load user");
}
}
// Чтение файла
Future<String> readFile(String path) async {
final file = File(path);
return await file.readAsString();
}
// Задержка (для тестирования)
Future<void> delayedPrint(String message) async {
await Future.delayed(Duration(seconds: 2));
print(message);
}
// Использование
final user = await fetchUser(1);
final content = await readFile("file.txt");
await delayedPrint("Done!");
Parallel выполнение с Future.wait()
// Выполнить несколько Future одновременно
Future<List<dynamic>> getMultipleData() async {
try {
final results = await Future.wait([
fetchUser(1),
fetchUser(2),
fetchUser(3),
]);
// results содержит результаты всех трёх запросов
return results;
} catch (e) {
print("Error: $e");
}
}
// Альтернатива с именованными переменными
Future<void> getMultipleDataNamed() async {
try {
final [user1, user2, user3] = await Future.wait([
fetchUser(1),
fetchUser(2),
fetchUser(3),
]);
print("$user1, $user2, $user3");
} catch (e) {
print("Error: $e");
}
}
Обработка ошибок в async функциях
// Try-catch для одной операции
async Future<void> safeFetch() async {
try {
final user = await fetchUser(1);
print(user);
} on SocketException catch (e) {
print("Network error: $e");
} on FormatException catch (e) {
print("Parse error: $e");
} catch (e) {
print("Unknown error: $e");
} finally {
print("Cleanup");
}
}
// Обработка одной ошибки из множества Future
Future<void> handleMultipleErrors() async {
try {
await Future.wait([
fetchUser(1),
fetchUser(999), // Ошибка
fetchUser(3),
]);
} catch (e) {
// Прерывается при первой ошибке
print("One failed: $e");
}
}
// Продолжить несмотря на ошибки
Future<void> handleAllErrors() async {
final results = await Future.wait(
[
fetchUser(1),
fetchUser(999),
fetchUser(3),
],
eagerError: false, // Не прерывать при ошибке
);
print(results); // Содержит успехи и ошибки
}
Timeout для Future
// Добавить таймаут
Future<User> fetchUserWithTimeout(int id) async {
try {
final user = await fetchUser(id).timeout(
Duration(seconds: 5),
onTimeout: () => throw TimeoutException(
"Request took too long",
),
);
return user;
} catch (e) {
print("Error: $e");
rethrow;
}
}
// Альтернатива
Future<User?> fetchUserOrNull(int id) async {
try {
return await fetchUser(id).timeout(
Duration(seconds: 5),
onTimeout: () => null,
);
} catch (e) {
return null;
}
}
Stream — последовательность значений
Stream похож на Future, но вместо одного значения возвращает несколько значений со временем:
// Future — одно значение
Future<int> getNumber() async {
await Future.delayed(Duration(seconds: 1));
return 42;
}
// Stream — несколько значений
Stream<int> getNumbers() async* {
for (int i = 1; i <= 5; i++) {
await Future.delayed(Duration(seconds: 1));
yield i; // Вернуть значение
}
}
// Использование Stream
await for (final number in getNumbers()) {
print(number); // Печатает 1, затем 2, затем 3...
}
// Или с listen
getNumbers().listen(
(number) => print(number),
onError: (e) => print("Error: $e"),
onDone: () => print("Finished"),
);
Сравнение: Future vs Stream
| Характеристика | Future | Stream |
|---|---|---|
| Значения | 1 | Много |
| Время | Один раз | Несколько раз |
| Завершение | Обязательно | Опционально |
| Пример | HTTP запрос | WebSocket, Timer |
Best Practices
- Предпочитайте async/await вместо .then()
- Используйте try-catch для обработки ошибок
- Future.wait() для параллельного выполнения
- Не забывайте await перед Future
- Используйте Stream для потока данных
- Добавляйте timeout для сетевых запросов
Итог
- Future — асинхронное значение с одним результатом
- async — ключевое слово для async функций
- await — ожидание Future (только в async функциях)
- Stream — последовательность значений
- Это основа асинхронного программирования во Flutter