# Isolates and the Event Loop in Depth — Dart

Source: https://www.skillbyai.com/en/dart/a-isolates

> Explain the event and microtask queues and move heavy work to isolates.

## Parallelism without shared memory

Each **isolate** has its own memory heap and a single thread running an **event loop**. The loop first drains the **microtask queue** (scheduled by `scheduleMicrotask` and completing futures) and then processes the next item from the **event queue** (timers, I/O, user input). Asynchronous code therefore keeps a single isolate responsive for I/O-bound work, but **CPU-heavy work** (parsing a huge JSON file, image processing, encryption, complex calculations) running on the main isolate blocks the event loop and freezes a Flutter UI. The fix is to run such work in **another isolate**. Isolates do **not share memory**: they communicate by **message passing** through ports, so there are no data races on shared objects. **`Isolate.run(() => heavyWork(data))`** (Dart 2.19+) is the simplest API: it spawns an isolate, runs the function, returns the result and shuts down. Flutter's `compute()` does the same. For long-lived background workers, use `Isolate.spawn` with `SendPort` and `ReceivePort`. On the web, isolates map to web workers with some limitations.

## Moving heavy parsing off the main isolate

Isolate.run keeps the UI isolate free while CPU work runs elsewhere.

```dart
import 'dart:async';
import 'dart:convert';
import 'dart:isolate';

class Order {
  Order(this.id, this.totalPaise);
  final String id;
  final int totalPaise;

  factory Order.fromJson(Map<String, dynamic> j) => Order(j['id'] as String, j['total_paise'] as int);
}

List<Order> parseOrders(String body) {
  final list = jsonDecode(body) as List<dynamic>;
  return [for (final item in list) Order.fromJson(item as Map<String, dynamic>)];
}

Future<int> totalRevenue(String hugeJsonBody) async {
  final orders = await Isolate.run(() => parseOrders(hugeJsonBody));   // runs in a new isolate
  return orders.fold<int>(0, (sum, o) => sum + o.totalPaise);
}

// event loop ordering example
void main() {
  print('1 sync');
  Future(() => print('4 event queue'));
  scheduleMicrotask(() => print('3 microtask'));
  print('2 sync');
}
```

## async does not mean parallel

Marking a CPU-heavy function `async` does not move it off the main isolate; it still blocks the event loop while it computes. Use `Isolate.run` for genuine parallel work.

**Quiz:** How do Dart isolates communicate?

- [x] By passing messages, since each isolate has its own memory
- [ ] By sharing objects in memory with locks
- [ ] Through global variables
- [ ] They cannot communicate

*Answer:* By passing messages, since each isolate has its own memory. Isolates have separate heaps and exchange data via messages.
