← Назад к вопросам

Как реализовать асинхронность в Dart?

2.0 Middle🔥 211 комментариев
#Dart#Асинхронность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Асинхронность в Dart: полный справочник

В Dart асинхронность реализована через несколько механизмов, которые позволяют выполнять операции без блокирования основного потока. Это критично для мобильных приложений, где долгие операции (сетевые запросы, работа с БД) могут "заморозить" UI.

1. Future

Future — это представление значения, которое может быть доступно сейчас, в будущем или никогда (ошибка).

// Простой Future
Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return "Данные загружены";
}

// Использование
fetchData().then((data) {
  print(data);
}).catchError((error) {
  print("Ошибка: $error");
});

2. Async/Await (рекомендуется)

Синтаксис async/await делает асинхронный код более читаемым и похожим на синхронный:

Future<String> fetchUserData() async {
  try {
    final response = await http.get(Uri.parse("https://api.example.com/user"));
    if (response.statusCode == 200) {
      return "Пользователь загружен";
    } else {
      throw Exception("Ошибка сервера");
    }
  } catch (e) {
    print("Ошибка сети: $e");
    return "Ошибка";
  }
}

3. Stream

Stream — это последовательность асинхронных событий. Используется для обработки множества значений во времени.

// Создание Stream
Stream<int> countStream() async* {
  for (int i = 1; i <= 5; i++) {
    await Future.delayed(Duration(seconds: 1));
    yield i; // Генерируем значение
  }
}

// Слушание Stream
countStream().listen((value) {
  print("Значение: $value");
});

// Или через async* с StreamBuilder в Flutter UI
StreamBuilder<int>(
  stream: countStream(),
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      return Text("Число: ${snapshot.data}");
    }
    return CircularProgressIndicator();
  },
)

4. Параллельные операции

Для выполнения нескольких асинхронных операций параллельно используй Future.wait():

Future<void> loadMultipleData() async {
  try {
    final results = await Future.wait([
      fetchUser(),
      fetchPosts(),
      fetchComments(),
    ]);
    print("Все данные загружены: $results");
  } catch (e) {
    print("Ошибка: $e");
  }
}

5. Isolate (для CPU-bound операций)

Для тяжёлых вычислений используй Isolate, чтобы не блокировать главный поток:

import "dart:isolate";

Future<int> heavyComputation(int count) async {
  return await compute(_fibonacci, count);
}

int _fibonacci(int n) {
  if (n <= 1) return n;
  return _fibonacci(n - 1) + _fibonacci(n - 2);
}

6. BLoC паттерн (для Flutter)

В настоящих Flutter приложениях асинхронность часто управляется через BLoC:

class DataBloc extends Bloc<DataEvent, DataState> {
  DataBloc() : super(DataInitial()) {
    on<FetchData>((event, emit) async {
      emit(DataLoading());
      try {
        final data = await _repository.fetchData();
        emit(DataLoaded(data));
      } catch (e) {
        emit(DataError(e.toString()));
      }
    });
  }
}

Правила и best practices

  • Всегда используй await для Future
  • Избегай вложенности (nested callbacks) — используй async/await
  • Обрабатывай ошибки через try/catch
  • Не забывай закрывать StreamSubscription через close()
  • Для длительных операций используй Isolate или compute()
  • В Flutter UI используй FutureBuilder, StreamBuilder или BLoC

Это основные способы работы с асинхронностью в Dart и Flutter. Выбор метода зависит от типа задачи.

Как реализовать асинхронность в Dart? | PrepBro