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

Какой тип данных возвращает Async метод?

1.0 Junior🔥 171 комментариев
#Dart

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

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

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

Тип данных, возвращаемый async методом в Dart

В Dart async методы возвращают Future — специальный тип данных, представляющий значение или ошибку, которые будут доступны в будущем.

1. Future — основной тип

// Async метод всегда возвращает Future
future<String> fetchUserName() async {
  await Future.delayed(Duration(seconds: 2));
  return 'John Doe';
}

// Вызов
Future<String> result = fetchUserName();

Если метод объявлен с async, то даже если вы явно не указываете Future, компилятор автоматически оборачивает возвращаемое значение в Future.

2. Future как контейнер

Future может находиться в трёх состояниях:

  1. Pending (ожидание) — асинхронная операция ещё не завершена
  2. Completed with value (завершено со значением) — операция прошла успешно
  3. Completed with error (завершено с ошибкой) — произошло исключение
// Генерирование Future со значением
Future<int> getValue() async {
  return 42;  // Будет завёрнуто в Future<int>
}

// Генерирование Future с ошибкой
Future<void> failOperation() async {
  throw Exception('Something went wrong');
}

3. Обработка Future: async/await

Это синтаксический сахар для работы с Future:

void main() async {
  // Ожидаем результат
  String name = await fetchUserName();
  print(name);  // John Doe
}

Future<String> fetchUserName() async {
  await Future.delayed(Duration(seconds: 1));
  return 'John Doe';
}

4. Обработка Future: then/catchError (старый способ)

fetchUserName().then((name) {
  print(name);  // John Doe
}).catchError((error) {
  print('Error: $error');
});

// Или с finally
fetchUserName()
  .then((name) => print(name))
  .catchError((error) => print('Error: $error'))
  .whenComplete(() => print('Done'));

5. Future vs Stream

Future — один результат в будущем

Future<String> getFutureData() async {
  return 'single value';
}

Stream — множество значений со временем

Stream<String> getStreamData() async* {
  yield 'first value';
  yield 'second value';
  yield 'third value';
}

6. Обработка нескольких Future параллельно

// Ждём все Future одновременно
Future.wait([
  fetchUser(),
  fetchPosts(),
  fetchComments(),
]);

// Ждём первый завершённый
Future.any([
  fetchFromServer1(),
  fetchFromServer2(),
  fetchFromServer3(),
]);

7. Практический пример в Flutter

class UserRepository {
  // Возвращает Future с объектом User
  Future<User> getUser(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');
    }
  }
}

// Использование в widget
class UserWidget extends StatelessWidget {
  final repo = UserRepository();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<User>(
      future: repo.getUser(1),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return CircularProgressIndicator();
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        } else {
          return Text('User: ${snapshot.data!.name}');
        }
      },
    );
  }
}

8. Типизированный Future

Future может быть типизирован на любой класс:

Future<String>              // Возвращает String
Future<int>                 // Возвращает int
Future<List<User>>          // Возвращает список User'ов
Future<Map<String, int>>    // Возвращает Map
Future<void>                // Не возвращает значение, но асинхронен

9. Ошибки в async методах

Future<String> riskyOperation() async {
  try {
    final result = await someAsyncCall();
    return result;
  } on TimeoutException {
    return 'Operation timed out';
  } on NetworkException catch (e) {
    return 'Network error: $e';
  } catch (e) {
    return 'Unknown error: $e';
  }
}

Ключевые моменты

  • Async метод ВСЕГДА возвращает Future, даже если забыть указать в типе — компилятор добавит
  • Future<T> — это контейнер для значения типа T
  • Async/await — удобный синтаксис для работы с Future
  • FutureBuilder — для отображения Future значений в UI
  • Future не блокирует главный поток (event loop в действии)

Без понимания Future и async/await невозможно писать асинхронный код в Flutter.