Назад к вопросам
Middle
180
questionbank

Что такое Completer в Dart и как его можно использовать в разработке на Flutter?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Completer — это класс в библиотеке dart:async, который позволяет создать Future и завершить его позже с некоторым значением или ошибкой. Он полезен, когда асинхронная операция не возвращает Future напрямую, но может быть уведомлена о ее завершении.

import 'dart:async';

void main() async {
  final completer = Completer<String>(); // Создаем Completer для Future<String>

  // Имитация асинхронной операции
  Future.delayed(Duration(seconds: 2), () {
    // Завершаем Future с успешным значением
    completer.complete("Операция завершена успешно!");
    // completer.completeError(StateError("Что-то пошло не так!")); // Или с ошибкой
  });

  print("Ожидаем завершения операции...");

  try {
    // Получаем Future из Completer и ждем его завершения
    final result = await completer.future;
    print("Результат: $result");
  } catch (e) {
    print("Произошла ошибка: $e");
  }
}

В Flutter Completer часто используется для:

  • Интеграции с нативными API: Когда нативный код вызывает обратный вызов (callback) при завершении операции, можно использовать Completer для преобразования этого в Future в Dart.
  • Реализации кастомных асинхронных операций: Если нужно создать асинхронную функцию, которая не использует существующие Future-возвращающие API.
  • Взаимодействия между изолятами: Для сигнализации о завершении работы в другом изоляте.

Пример использования в Flutter с нативным API (гипотетический):

import 'dart:async';
import 'package:flutter/services.dart';

class NativeService {
  static const platform = MethodChannel('com.example/native_service');

  Future<String> performNativeOperation() async {
    final completer = Completer<String>();

    try {
      final result = await platform.invokeMethod('startOperation');

      // Предполагается, что нативный код вызовет метод 'operationCompleted'
      // с результатом или ошибкой, и мы слушаем эти вызовы.
      platform.setMethodCallHandler((call) async {
        if (call.method == 'operationCompleted') {
          if (call.arguments is String) {
            completer.complete(call.arguments as String);
          } else if (call.arguments is PlatformException) {
            completer.completeError(call.arguments as PlatformException);
          } else {
            completer.completeError(StateError("Неизвестный результат нативной операции"));
          }
          // Удалить обработчик, если больше не нужен
          platform.setMethodCallHandler(null);
        }
        return true; // Указываем, что вызов обработан
      });

    } on PlatformException catch (e) {
      completer.completeError(e);
    }

    return completer.future; // Возвращаем Future, которое будет завершено позже
  }
}

// В виджете или другом месте:
// final service = NativeService();
// try {
//   final nativeResult = await service.performNativeOperation();
//   print("Нативный результат: $nativeResult");
// } catch (e) {
//   print("Ошибка нативной операции: $e");
// }