Что такое изоляты (Isolates) в Dart и зачем они нужны?

«Что такое изоляты (Isolates) в Dart и зачем они нужны?» — вопрос из категории Асинхронность, который задают на 59% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Изоляты (Isolates) — это модель параллельных вычислений в Dart, основанная на передаче сообщений. Каждый изолят имеет свою собственную выделенную память (кучу) и работает в отдельном потоке. Ключевая особенность — отсутствие разделяемой памяти, что исключает состояние гонки (race conditions) и необходимость в блокировках (locks).

Зачем они нужны в Flutter? Для выполнения ресурсоемких задач (тяжелые вычисления, обработка изображений, парсинг больших JSON) без блокировки основного UI-потока.

Пример: Вычисление числа Фибоначчи в отдельном изоляте.

import 'dart:isolate';

// Функция, которая будет запущена в изоляте
void _fibonacciIsolate(SendPort sendPort) {
  // Принимаем порт для ответа
  final receivePort = ReceivePort();
  sendPort.send(receivePort.sendPort);

  // Ожидаем сообщение с данными для расчета
  receivePort.listen((message) {
    if (message is int) {
      int result = _calculateFibonacci(message);
      // Отправляем результат обратно в главный изолят
      sendPort.send(result);
    }
  });
}

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

// Использование в основном потоке Flutter
Future<void> computeHeavyTask() async {
  final receivePort = ReceivePort();

  // Создаем изолят
  await Isolate.spawn(_fibonacciIsolate, receivePort.sendPort);

  // Получаем порт для связи с созданным изолятом
  final SendPort childSendPort = await receivePort.first as SendPort;

  // Отправляем задание (вычислить 40-е число Фибоначчи)
  childSendPort.send(40);

  // Ожидаем результат
  receivePort.listen((result) {
    if (result is int) {
      print('Результат из изолята: $result');
      // Обновляем UI через setState или провайдер
      // setState(() => _result = result);
      receivePort.close(); // Закрываем порт
    }
  });
}

Альтернативы для Flutter: Для большинства задач проще использовать compute() — высокоуровневую обертку над изолятами.

int fib(int n) => n <= 1 ? n : fib(n-1) + fib(n-2);

void main() async {
  // compute автоматически создаст изолят, выполнит функцию и вернет результат
  final result = await compute(fib, 40);
  print(result);
}