通过函数扩展的方式,调用时只要在原有函数后面加上对应方法即可。

import 'dart:async';
import 'dart:ui';

// Function extensions to add throttling and debouncing capabilities
extension FunctionExtensions on Function {
  VoidCallback throttle() {
    return FunctionProxy(this).throttle;
  }

  VoidCallback throttleWithTimeout({int? timeout}) {
    return FunctionProxy(this, timeout: timeout).throttleWithTimeout;
  }

  VoidCallback debounce({int? timeout}) {
    return FunctionProxy(this, timeout: timeout).debounce;
  }
}

// FunctionProxy class to implement throttling and debouncing
class FunctionProxy {
  static final Map<int, bool> _throttleMap = {};
  static final Map<int, Timer> _debounceMap = {};
  final Function target;
  final int timeout;

  FunctionProxy(this.target, {int? timeout}) : timeout = timeout ?? 500;

  // Throttle function to limit the execution rate
  void throttle() async {
    int key = target.hashCode;
    bool canExecute = _throttleMap[key] ?? true;
    if (canExecute) {
      _throttleMap[key] = false;
      try {
        await target();
      } catch (e) {
        rethrow;
      } finally {
        _throttleMap.remove(key);
      }
    }
  }

  // Throttle function with a specified timeout
  void throttleWithTimeout() {
    int key = target.hashCode;
    bool canExecute = _throttleMap[key] ?? true;
    if (canExecute) {
      _throttleMap[key] = false;
      Timer(Duration(milliseconds: timeout), () {
        _throttleMap.remove(key);
      });
      target();
    }
  }

  // Debounce function to delay execution until after a specified period
  void debounce() {
    int key = target.hashCode;
    _debounceMap[key]?.cancel();
    _debounceMap[key] = Timer(Duration(milliseconds: timeout), () {
      _debounceMap.remove(key);
      target();
    });
  }
}