request<R> method

Future<R> request<R>(
  1. String command, {
  2. Map<String, Object?>? data,
  3. Duration timeout = const Duration(seconds: 3),
})

Send a typed request to Web Worker and await the response.

Creates a dedicated MessageChannel for the reply, sends the request, and waits for exactly one response. Perfect for offloading CPU-intensive work to Web Workers while maintaining type safety.

Parameters:

  • command: Command string for the worker
  • data: Optional data payload
  • timeout: Maximum wait time (default: 3 seconds)

Web Worker Processing:

// Main thread - send heavy computation to worker
final result = await workerPort.request<ProcessingResult>(
  'analyze_data',
  data: {
    'dataset': largeDataset,
    'algorithm': 'machine_learning'
  },
  timeout: Duration(minutes: 5),
);

Image Processing:

// Offload image filters to Web Worker
final filteredImage = await imageWorkerPort.request<ImageData>(
  'apply_filters',
  data: {
    'image': originalImage,
    'filters': ['gaussian_blur', 'edge_detection']
  },
);

Crypto Operations:

// Secure hashing in Web Worker
final hash = await cryptoWorkerPort.request<String>(
  'compute_hash',
  data: {'algorithm': 'SHA-256', 'data': sensitiveData},
);

Implementation

Future<R> request<R>(
  String command, {
  Map<String, Object?>? data,
  Duration timeout = const Duration(seconds: 3),
}) async {
  final completer = Completer<Object?>();
  final reply = MessageChannel();

  reply.port2.onmessage = ((MessageEvent msg) {
    if (completer.isCompleted) return;
    completer.complete(msg.data?.dartify());
  }).toJS;

  sendCmd(
    command,
    data: {...?data, 'reply': reply.port1},
    transfer: reply.port1,
  );

  try {
    final obj = await completer.future.timeout(
      timeout,
      onTimeout: () {
        throw TimeoutException(
          'request("$command") timed out after $timeout',
        );
      },
    );

    if (obj is Map && obj['error'] != null) {
      throw StateError('request("$command") failed: ${obj['error']}');
    }

    try {
      return obj as R;
    } on TypeError {
      throw StateError(
        'request("$command") returned incompatible type: ${obj.runtimeType} expected: $R',
      );
    }
  } finally {
    reply.port1.close();
    reply.port2.close();
  }
}