likes
comments
collection
share

dev_prokit 之事件节流和防抖

作者站长头像
站长
· 阅读数 32

往期优选推荐

推荐指数: ⭐️⭐️⭐️⭐️⭐️

》fam 和 flutter_gen 相比优点《

  1. fam 不需要在项目的 pubspec.yaml 文件的 dev_dependencies 引入任何东西;而 flutter_gen 需要引入 flutter_gen_runner

  2. fam 在导入资源后只需要执行 fam run 即可;而 flutter_gen 需要执行 dart run build_runner build 。需要注意的是 dart run build_runner build 是很多代码自动生成的运行指令(多语言、json解析、rividerpod...等)。所以一旦执行就需要很长时间才能完成,而 fam 拥有独立的体系,便捷快速!

  3. fam 的资源管理类在项目中使用简短;而 flutter_gen 需要使用.语法一直到资源文件,然后再通过 .path 获取资源路径,这很麻烦!

  4. fam 拥有独立的系统体系; flutter_gen 和多语言的使用有一定的冲突。

推荐指数: ⭐️⭐️⭐️⭐️⭐️

该篇文章包含了 dev_prokit 所有功能介绍和示例的目录。此文章能够让开发者快速的了解 dev_prokit 都提供了那些功能,以及能更快速的找到自己需要的功能介绍和应用。

本期功能介绍

一、起因

在日常的开发过程中,我们经常会遇到这样的业务场景:需要在某个事件触发后,确保在特定的时间段内不再频繁响应该事件,或者是在一定的时间间隔内,无论该事件被触发多少次,都仅执行一次处理逻辑。这类场景常见于按钮点击事件、输入框内容变化事件等。针对这类需求,我们通常采用的技术手段就是事件节流(Throttling)和防抖(Debouncing)

二、节流和防抖

  • 节流

    事件节流(Throttling)是一种优化高频率触发事件的技术,用于限制某个事件在单位时间内的触发频率。在高频率触发的事件(如滚动、窗口大小调整、鼠标移动等)中,如果不加以限制,可能会导致性能问题或不必要的计算开销。事件节流通过减少事件处理函数的执行次数,来确保在一段时间内只执行一次处理逻辑。

  • 防抖

    事件防抖(Debouncing)是一种优化高频率触发事件的技术,用于确保事件被触发后,在指定的等待时间内没有再次被触发,才执行处理函数。这通常用于处理如输入框内容变化、窗口大小调整、按钮点击等事件,以防止因连续触发而导致的不必要计算或性能问题。

三、功能介绍

dev_prokit 为开发提供了事件的节流和防抖功能,功能介绍如下:

  • 节流

    1. Function() throttle([int millisecond = 200]){...}

      该方法是无参数事件进行节流处理方法,默认时间是 200 毫秒

    2. Function(T) throttleParam<T>([int millisecond = 200]){...}

      该方法是带有一个参数的事件进行节流处理方法,默认时间是 200 毫秒

    3. Function(T, K) throttleParam2<T, K>([int millisecond = 200]){...}

      该方法是带有两个参数的事件进行节流处理方法,默认时间是 200 毫秒

    注意📢 :

    在软件开发过程中,当面对由开发团队内部或第三方提供的事件时,若这些事件携带的参数超过两个,而我们又有需求对其进行节流(即限制其触发频率),一个优雅的解决方案便是创建一个自定义的中间事件进行中转。这一中间事件应设计为最多只接受两个参数或者一个参数,从而便于我们对其进行节流处理。示例如下:

    // An event provided by a third party.
    class HomeWidget extends StatelessWidget {
      const HomeWidget({super.key, this.homeInfoMethod});
      final Function(String,String,int) homeInfoMethod;
    }
    
    // Define transit events :
    Function(String,(String,int)) diyHomeMethod = (name,(address, age)){
      print('$name-$address-$age');
    }.throttleParam2();
    
    // Use :
    HomeWidget(
      homeInfoMethod:(name, address, age) {
        diyHomeMethod(name,(address,age));
      }
    )
    
  • 防抖

    1. Function() debounce([int millisecond = 200]){...}

      该方法是无参数事件进行防抖处理方法,默认时间是 200 毫秒

    2. Function(T) debounceParam<T>([int millisecond = 200]){...}

      该方法是带有一个参数的事件进行防抖处理方法,默认时间是 200 毫秒

    3. Function(T, K) debounceParam2<T, K>([int millisecond = 200]){...}

      该方法是带有两个参数的事件进行防抖处理方法,默认时间是 200 毫秒

    注意📢 :

    在软件开发过程中,当面对由开发团队内部或第三方提供的事件时,若这些事件携带的参数超过两个,而我们又有需求对其进行防抖(即限制其触发频率),一个优雅的解决方案便是创建一个自定义的中间事件进行中转。这一中间事件应设计为最多只接受两个参数或者一个参数,从而便于我们对其进行防抖处理。示例如下:

    // An event provided by a third party.
    class HomeWidget extends StatelessWidget {
      const HomeWidget({super.key, this.homeInfoMethod});
      final Function(String,String,int) homeInfoMethod;
    }
    
    // Define transit events :
    Function(String,(String,int)) diyHomeMethod = (name,(address, age)){
      print('$name-$address-$age');
    }.debounceParam2();
    
    // Use :
    HomeWidget(
      homeInfoMethod:(name, address, age) {
        diyHomeMethod(name,(address,age));
      }
    )
    

四、小试牛刀

我们使用 dev_prokit 的提供的方法进行事件的节流和防抖,如下:

  • 默认形式

    // throttle
    InkWell(
      onTap: () {
        debugPrint('事件节流触发');
      }.throttle(),
      child: const Text('事件节流'),
    )
    
    // debounce
    InkWell(
      onTap: () {
        debugPrint('事件防抖触发');
      }.debounce(),
      child: const Text('事件防抖'),
    )
    
  • 修改时间 (单位毫秒,默认: 200 ms)

    // throttle
    GestureDetector(
      onTap: () {
        debugPrint('事件节流触发');
      }.throttle(1000),
      child: const Text('事件节流'),
    )
    
    // debounce
    GestureDetector(
      onTap: () {
        debugPrint('事件防抖触发');
      }.debounce(2000),
      child: const Text('事件防抖'),
    )
    
  • 单个参数事件

    // throttle
    GestureDetector(
      onTapDown: (details)
        debugPrint('事件节流触发');
      }.throttleParam(1000),
      child: const Text('事件节流'),
    )
    
    // debounce
    GestureDetector(
      onTapDown: (details) {
        debugPrint('事件防抖触发');
      }.debounceParam(2000),
      child: const Text('事件防抖'),
    )
    
  • 两个参数事件

    系统提供的按钮(GestureDetector/InkWell/Listener...)事件没有两个参数的。一般见到的包含两个参数的事件一部分是自己定义的和一些第三方包提供的(按理说这都属于自定义)。示例如下:

    // 自定义或者第三方
    class MainMethod extends StatelessWidget {
      const MainMethod({super.key, this.infoMethod});
      final Function(String, int)? infoMethod;
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () => infoMethod?.call('姓名', 10),
          child: const Text('信息回调'),
        );
      }
    }
    
    // debounce
    MainMethod(
      infoMethod: (p0, p1) {
        debugPrint('name:$p0-age:$p1');
      }.debounceParam2(),
    ),
    
    // throttle
    MainMethod(
      infoMethod: (p0, p1) {
        debugPrint('name:$p0-age:$p1');
      }.throttleParam2(),
    )
    
  • 大于两个参数的事件

    两个参数的事件在开发者已经不是很常见了,至于两个以上的参数事件更是少的可怜。但是第三方或者内部团队提供的事件中还是有两个以上的参数事件的。我们想给这种事件进行节流和防抖该如何处理?dev_prokit 也只提供两个参数以内的事件进行节流和防抖的方法, 不支持两个以上的参数事件。针对这个问题,我们又不能修改第三方或者团队提供的方法,那该如何处理呢?答: 我们 可以自定义一个不多于两个的参数事件进行中转多参数事件,然后我们对自定义的事件进行节流或者防抖。示例如下:

    // 自定义或者第三方
    class MainMethod extends StatelessWidget {
      const MainMethod({super.key, this.infoMethod});
      final Function(String,String, int)? infoMethod;
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () => infoMethod?.call('姓名','中国' ,10),
          child: const Text('信息回调'),
        );
      }
    }
    
    // 自定义方法中转
    // debounce
    Function(String,(String,int)) diyInfoMethod = (name,(address, age)) {
        print('多参数事件中转');
    }.debounceParam2(),
    
    // throttle
    Function(String,(String,int)) diyInfoMethod = (name,(address, age)) {
        print('多参数事件中转');
    }.throttleParam2(),
    
    // 调用
    MainMethod(
      infoMethod: (p0, p1, p2) {
        diyInfoMethod(p0,(p1,p2));
      }
    ),
    

五、鼓励与支持

这便是 dev_prokit 提供的方法之一。以编写代码较少、功能完善、代码运行强壮、支持面广等形式来开发 dev_prokit 包。 如果你有 Idea 或者 Opinion ,那请你点击此处 》》Idea & Opinion《《 把它留下吧!如果你在使用该功能后感觉还可以,它能够给你的项目开发带来便捷,那请你为之点个⭐️ dev_prokit ⭐️ 吧!分享给更多需要它的开发者。

转载自:https://juejin.cn/post/7372078061896106021
评论
请登录