Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Асинхронность в программировании
Асинхронность — это подход к выполнению кода, при котором операция запускается, но программа не ждёт её завершения. Вместо этого код продолжает выполняться дальше, а результат обрабатывается когда он готов.
Синхронность vs Асинхронность
Синхронный код:
print('Start');
final data = fetchData(); // Ждём 2 секунды
print(data);
print('End');
// Вывод:
// Start
// (ждём 2 секунды)
// Loaded data
// End
Асинхронный код:
print('Start');
fetchData().then((data) {
print(data);
});
print('End');
// Вывод:
// Start
// End
// (спустя 2 секунды)
// Loaded data
Проблема синхронности
Если блокировать UI thread синхронной операцией, приложение "зависает":
void onButtonPress() {
final data = fetchDataSync(); // Зависает на 2 секунды!
setState(() => this.data = data);
}
Пользователь видит frozen UI и не может взаимодействовать с приложением.
Асинхронность решает эту проблему
void onButtonPress() async {
final data = await fetchData(); // Не блокирует UI
setState(() => this.data = data);
}
// UI остаётся responsive
Уровни асинхронности
1. Callback Hell:
fetchUser(userId, (user) {
fetchPosts(user.id, (posts) {
fetchComments(posts[0].id, (comments) {
// Читаемость страдает
});
});
});
2. Promise-like (Future):
fetchUser(userId)
.then((user) => fetchPosts(user.id))
.then((posts) => fetchComments(posts[0].id))
.then((comments) => print(comments));
3. async/await (лучше всего):
final user = await fetchUser(userId);
final posts = await fetchPosts(user.id);
final comments = await fetchComments(posts[0].id);
print(comments);
Event Loop: как это работает
print('1. Sync start');
Future(() => print('2. Future'));
print('3. Sync end');
// Вывод:
// 1. Sync start
// 3. Sync end
// 2. Future
Dart использует Event Loop, который выполняет:
- Весь синхронный код
- Microtasks (Future callbacks)
- Macrotasks (I/O, timers)
Параллельные асинхронные операции
// Плохо: последовательно (занимает 6 секунд)
final user = await fetchUser(); // 2 сек
final posts = await fetchPosts(); // 2 сек
final settings = await fetchSettings(); // 2 сек
// Хорошо: параллельно (занимает 2 секунды)
final results = await Future.wait([
fetchUser(),
fetchPosts(),
fetchSettings(),
]);
final user = results[0];
final posts = results[1];
final settings = results[2];
Streams: асинхронность с множеством значений
Eсли Future = одно значение в будущем, то Stream = множество значений во времени.
// Real-time обновления
Stream<ChatMessage> messages = chatRepository.getMessages();
messages.listen((message) {
print('New message: ${message.text}');
});
Обработка ошибок в асинхронном коде
try {
final data = await fetchData();
print(data);
} on TimeoutException catch (e) {
print('Request timed out');
} on DioException catch (e) {
print('Network error: ${e.message}');
} catch (e) {
print('Unknown error: $e');
}
Race Conditions в асинхронности
// Проблема: два запроса одновременно
var lastResult;
void search(String query) async {
final result = await api.search(query);
lastResult = result; // Может быть перезаписан!
}
search('flutter');
search('dart');
// Какой результат в lastResult? Непредсказуемо!
// Решение: используйте CancelToken
CancelToken _cancelToken = CancelToken();
void search(String query) async {
_cancelToken.cancel();
_cancelToken = CancelToken();
final result = await api.search(
query,
cancelToken: _cancelToken,
);
setState(() => lastResult = result);
}
Распространённые ошибки
// Ошибка 1: забыли await
final data = fetchData(); // Это Future, а не данные!
print(data); // Instance of 'Future'
// Ошибка 2: не обработали ошибку
await fetchData(); // Если упадёт, упадёт всё
// Ошибка 3: утечка памяти с Streams
Stream stream = someStream();
stream.listen((_) {}); // Забыли отменить подписку!
Лучшие практики
- Используйте async/await вместо .then()
- Всегда обрабатывайте ошибки — try-catch
- Отменяйте подписки — StreamSubscription.cancel()
- Используйте Future.wait для параллельных операций
- Избегайте race conditions — используйте CancelToken
- Профилируйте — асинхронность может затянуть загрузку
Асинхронность — это основа responsive приложений. Без неё Flutter приложение будет зависать при любом сетевом запросе или IO операции.