debounceFuture<T> method

Future<T?> debounceFuture<T>({
  1. required Duration duration,
  2. List<Object?> positionalArgs = const [],
  3. Map<Symbol, Object?> namedArgs = const {},
})

针对future的防抖 推荐在无参数输入的场景下使用

Implementation

Future<T?> debounceFuture<T>({
  required Duration duration,
  List<Object?> positionalArgs = const [],
  Map<Symbol, Object?> namedArgs = const {},
}) {
  late final String key;
  if (positionalArgs.isEmpty && namedArgs.isEmpty) {
    key = this.hashCode.toString();
  } else {
    final keyBuffer = StringBuffer();
    keyBuffer.write(this.hashCode);
    for (final arg in positionalArgs) {
      keyBuffer.write('_');
      keyBuffer.write(arg.hashCode);
    }
    for (final entry in namedArgs.entries) {
      keyBuffer.write('_');
      keyBuffer.write(entry.key.hashCode);
      keyBuffer.write('_');
      keyBuffer.write(entry.value.hashCode);
    }
    key = keyBuffer.toString();
  }
  final now = DateTime.now();

  _DebounceData? data = ThrottleUtil.instance.debounceCache[key];
  data?.timer?.cancel();

  final completer = Completer<T?>();

  final timer = Timer(duration, () {
    ThrottleUtil.instance.debounceCache.remove(key);
    final future =
        Function.apply(this, positionalArgs, namedArgs) as Future<T>;
    future
        .then((value) {
          if (!completer.isCompleted) completer.complete(value);
        })
        .catchError((error) {
          if (!completer.isCompleted) completer.completeError(error);
          throw error;
        });
  });

  ThrottleUtil.instance.debounceCache[key] = _DebounceData(
    lastCall: now,
    timer: timer,
  );

  return completer.future;
}