import 'dart:async'; import 'dart:ui'; extension FunctionExt 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; } } class FunctionProxy { static final Map _funcThrottle = {}; static final Map _funcDebounce = {}; final Function? target; final int timeout; FunctionProxy(this.target, {int? timeout}) : timeout = timeout ?? 500; void throttle() async { String key = hashCode.toString(); bool enable = _funcThrottle[key] ?? true; if (enable) { _funcThrottle[key] = false; try { await target?.call(); } catch (e) { rethrow; } finally { _funcThrottle.remove(key); } } } void throttleWithTimeout() { String key = hashCode.toString(); bool enable = _funcThrottle[key] ?? true; if (enable) { _funcThrottle[key] = false; Timer(Duration(milliseconds: timeout), () { _funcThrottle.remove(key); }); target?.call(); } } void debounce() { String key = hashCode.toString(); Timer? timer = _funcDebounce[key]; timer?.cancel(); timer = Timer(Duration(milliseconds: timeout), () { Timer? t = _funcDebounce.remove(key); t?.cancel(); target?.call(); }); _funcDebounce[key] = timer; } }