dart 扩展函数实现防抖跟节流

61 阅读1分钟

原文地址:juejin.cn/post/732920…

// 扩展Function,添加防抖功能
extension DebounceExtension on Function {
  void Function() debounce([int milliseconds = 500]) {
    Timer? _debounceTimer;
    return () {
      if (_debounceTimer?.isActive ?? false) _debounceTimer?.cancel();
      _debounceTimer = Timer(Duration(milliseconds: milliseconds), this);
    };
  }
}

// 扩展Function,添加节流功能
extension ThrottleExtension on Function {
  void Function() throttle([int milliseconds = 500]) {
    bool _isAllowed = true;
    Timer? _throttleTimer;
    return () {
      if (!_isAllowed) return;
      _isAllowed = false;
      this();
      _throttleTimer?.cancel();
      _throttleTimer = Timer(Duration(milliseconds: milliseconds), () {
        _isAllowed = true;
      });
    };
  }
}
//点击防抖类型
enum ClickType { none, throttle, debounce }

 /// 手势
  Widget onTap(
    GestureTapCallback onTap, {
    Key? key,
    HitTestBehavior? behavior,
    ClickType type = ClickType.none, //默认没有点击类型
    int milliseconds = 500, //点击类型的时间戳(毫秒)
    bool excludeFromSemantics = false,
    DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  }) =>
      GestureDetector(
        key: key,
        onTap: type == ClickType.debounce
            ? onTap.debounce(milliseconds)
            : type == ClickType.throttle
                ? onTap.throttle(milliseconds)
                : onTap,
        behavior: behavior ?? HitTestBehavior.opaque,
        excludeFromSemantics: excludeFromSemantics,
        dragStartBehavior: dragStartBehavior,
        child: this,
      );

简单理解:onTap.debounce(milliseconds) 返回的是一个方法。所以相当于每次点击执行的是返回的方法。这个返回的方法是可以访问到扩展中的_debounceTimer对象,所以就可以通过 _debounceTimer变量状态来控制节流跟防抖。