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,通过点击事件触发的时间自行判断处理。

相关推荐
风华圆舞5 小时前
Flutter + 鸿蒙 Intents Kit:页面直达能力的完整接入方案
flutter·ui·华为·harmonyos
韩曙亮5 小时前
【Flutter】Flutter 组件 ④ ( 组件渲染 的 三棵树理论 | Widget 树 → Element 树 → RenderObject 树 )
flutter·element·widget·renderobject
恋猫de小郭8 小时前
Android 17 正式版发布,全新 AI 和各种破坏性更新
android·前端·flutter
kingbal8 小时前
Windows:flutter环境搭建
windows·flutter
911hzh9 小时前
Flutter MethodChannel 跨端通信框架 zh_native_channel:快速入门、优势分析与 Pigeon 对比
flutter
911hzh9 小时前
Flutter 快速搭建新项目:用 Flutter Foundation Kit 一条命令生成带基础架构的 App 模板
flutter
kingbal10 小时前
Flutter:Flutter SDK版本管理工具FVM
android·flutter·ios·android-studio·window
风华圆舞10 小时前
鸿蒙 Flutter 页面怎么感知防窥状态并调整 UI 可见性
flutter·ui·harmonyos
天天开发10 小时前
Flutter状态管理新宠:RiverPod全面解析与实战指南
android·flutter