deduplicate<T> static method

Future<T> deduplicate<T>(
  1. List key,
  2. Future<T> fetcher()
)

Deduplicates concurrent asynchronous requests sharing the same cache key.

If a request for key is already in-flight, returns the existing active Future. Otherwise, executes fetcher, broadcasts the result to all callers, and cleans up upon completion.

final result = await BloomData.deduplicate(['items'], () => client.get('/items'));

Implementation

static Future<T> deduplicate<T>(List<dynamic> key, Future<T> Function() fetcher) {
  final keyStr = normalizeKey(key);
  if (_inFlightRequests.containsKey(keyStr)) {
    return _inFlightRequests[keyStr]!.future as Future<T>;
  }

  final completer = Completer<T>();
  _inFlightRequests[keyStr] = completer;

  fetcher().then((val) {
    _inFlightRequests.remove(keyStr);
    completer.complete(val);
  }).catchError((Object err, StackTrace st) {
    _inFlightRequests.remove(keyStr);
    completer.completeError(err, st);
  });

  return completer.future;
}