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

相关推荐
Jinkey11 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
Summer不秃15 小时前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰15 小时前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
sunly_15 小时前
Flutter:AnimatedSwitcher当子元素改变时,触发动画
flutter
AiFlutter15 小时前
Flutter封装Coap
flutter
旭日猎鹰21 小时前
Flutter踩坑记录(三)-- 更改入口执行文件
flutter
旭日猎鹰21 小时前
Flutter踩坑记录(一)debug运行生成的项目,不能手动点击运行
flutter
️ 邪神21 小时前
【Android、IOS、Flutter、鸿蒙、ReactNative 】自定义View
flutter·ios·鸿蒙·reactnative·anroid
比格丽巴格丽抱1 天前
flutter项目苹果编译运行打包上线
flutter·ios
SoaringHeart1 天前
Flutter进阶:基于 MLKit 的 OCR 文字识别
前端·flutter