Sobes.tech
Назад к вопросам
Junior — Middle
97

Каким образом реализована поддержка параллелизма и асинхронности в Dart?

Компании, где спрашивали
WildberriesWildberries

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

sobes.tech AI

Что хотят услышать интервьюеры:

В Dart параллелизм и асинхронность решаются разными механизмами: async/await, Future и Stream — для неблокирующей работы внутри одного изолята. Для настоящего параллелизма используются изоляты (Isolate), потому что они не делят память между собой. Это позволяет не блокировать UI в Flutter и выносить тяжёлую работу в фон.

Определение:

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

Параллелизм в Dart реализован через изоляты. Каждый изолят имеет собственную память и event loop, поэтому код в разных изолятах действительно может выполняться одновременно на разных ядрах процессора. Общение между ними идёт через передачу сообщений, а не через общие объекты.

Пример использования:

Например, в Flutter нужно загрузить данные с сервера и одновременно не заморозить интерфейс, а затем отдельно посчитать тяжёлую обработку JSON.

import 'dart:convert';
import 'dart:isolate';

Future<void> loadData() async {
  final response = await fetchFromServer();
  final result = await computeInIsolate(response);
  print(result);
}

Future<String> fetchFromServer() async {
  await Future.delayed(const Duration(seconds: 1));
  return '{"name":"Dart"}';
}

Future<Map<String, dynamic>> computeInIsolate(String jsonText) async {
  final port = ReceivePort();
  await Isolate.spawn(_parseJson, port.sendPort);

  final sendPort = await port.first as SendPort;
  final answerPort = ReceivePort();

  sendPort.send([jsonText, answerPort.sendPort]);

  return await answerPort.first as Map<String, dynamic>;
}

void _parseJson(SendPort initialReplyTo) async {
  final port = ReceivePort();
  initialReplyTo.send(port.sendPort);

  await for (final message in port) {
    final data = message as List;
    final jsonText = data[0] as String;
    final replyTo = data[1] as SendPort;

    final parsed = jsonDecode(jsonText) as Map<String, dynamic>;
    replyTo.send(parsed);
  }
}

Пояснение кода:

Код показывает два уровня работы.

Сначала fetchFromServer() использует Future и await, чтобы не блокировать поток во время ожидания результата. Это асинхронность, но не параллельное выполнение тяжёлой вычислительной задачи.

Затем computeInIsolate() создаёт новый изолят через Isolate.spawn(). Основной изолят отправляет строку JSON в дочерний изолят через SendPort, а дочерний изолят парсит JSON отдельно и возвращает результат обратно через ReceivePort.

Таким образом:

  1. UI-поток не блокируется.
  2. Ожидание сети выполняется асинхронно.
  3. Парсинг выполняется в отдельном изоляте параллельно основному коду.

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

  • Future и async/await нужны для асинхронного кода без блокировки потока.
  • Stream используется для последовательности значений или событий во времени.
  • Isolate — основной механизм параллелизма в Dart.
  • Изоляты не разделяют память; взаимодействие только через сообщения.
  • Для Flutter это критично, чтобы не блокировать главный UI-поток.
  • Future не даёт параллелизма сам по себе: он лишь делает ожидание неблокирующим.