Flutter自定义通用防抖的实现

在前端项目开发中,点击事件的防抖是一个永远无法错开的点,特别是针对一些复杂的业务场景,如果不做好防抖操作,就会导致页面或功能触发多次,引发异常或闪退。

在Flutter中可以通过扩展函数的特性 对Function增加全局扩展函数,实现防抖效果。

具体如下:

Dart 复制代码
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<String, bool> _funcThrottle = {};
  static final Map<String, Timer> _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;
  }
}

在使用的地方

Dart 复制代码
              onBackPressed: () {
              }.throttleWithTimeout(timeout: 500)

这种方案只是提供了一种防抖的实现,当然也可以自定义通用的Button,通过点击事件触发的时间自行判断处理。

相关推荐
火柴就是我4 小时前
flutter 之真手势冲突处理
android·flutter
Speed1234 小时前
`mockito` 的核心“打桩”规则
flutter·dart
法的空间5 小时前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
恋猫de小郭5 小时前
Android 将强制应用使用主题图标,你怎么看?
android·前端·flutter
玲珑Felone6 小时前
从flutter源码看其渲染机制
android·flutter
ALLIN1 天前
Flutter 三种方式实现页面切换后保持原页面状态
flutter
Dabei1 天前
Flutter 国际化
flutter
Dabei1 天前
Flutter MQTT 通信文档
flutter
Dabei1 天前
Flutter 中实现 TCP 通信
flutter
孤鸿玉1 天前
ios flutter_echarts 不在当前屏幕 白屏修复
flutter