• flutter开发实战-防抖Debounce与节流Throttler实现


    flutter开发实战-防抖Debounce与节流Throttler实现

    在开发中,经常遇到某些按钮或者界面操作需要做防抖或者节流操作。这里记录一下实现。

    一、防抖Debounce与节流Throttler

    • 防抖Debounce

    当有可能在短时间内对一个方法进行多次调用时,需要防抖,并且希望只有最后一次调用真正调用目标方法。因此,基本上每个调用都会启动一个计时器,如果在计时器执行之前发生另一个调用,则计时器会重置并再次开始等待所需的持续时间。当计时器最终超时时,将调用目标方法。

    • 节流Throttler

    Throttling与debouncing有点相反——只有对方法的第一次调用才真正调用该方法,并且在指定的持续时间内进行的任何后续调用都将被忽略。例如,这对于限制刷新按钮的按下量非常有用。

    二、实现防抖

    防抖的实现基本上是每个调用都会启动一个计时器,如果在计时器执行之前发生另一个调用,则计时器会重置并再次开始等待所需的持续时间。当计时器最终超时时,将调用目标方法。

    所以我们来定义一个防抖的类。

    import 'dart:async';
    
    import 'package:flutter/foundation.dart';
    
    class Debouncer {
      final int milliseconds;
      Timer? _timer;
    
      Debouncer({required this.milliseconds});
    
      void run(VoidCallback action) {
        _timer?.cancel();
        _timer = Timer(Duration(milliseconds: milliseconds), action);
      }
    
      void dispose() {
        _timer?.cancel();
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    通过使用Debouncer

    // 防抖
      final _debouncer = Debouncer(milliseconds: 5000);
    
    
      void testDebouncer(BuildContext context) {
        _debouncer.run(() {
          print("testDebouncer time:${DateTime.now()}");
        });
      }
    
      
      void dispose() {
        // TODO: implement dispose
        super.dispose();
        _debouncer.dispose();
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    测试结果如下

    flutter: testDebouncer time:2023-10-16 10:40:11.573277

    在多次点击时候,只有当5s倒计时结束之后,才打印了一条。

    三、实现节流

    Throttling是第一次调用才是真正调用该方法,在持续的时间内后续的调用,均被忽略。

    所以我们来定义一个节流的类

    import 'dart:async';
    
    import 'package:flutter/foundation.dart';
    
    class Throttler {
      final int milliseconds;
      Timer? _timer;
      bool isExecuted = false;
    
      Throttler({required this.milliseconds});
    
      void run(VoidCallback action) {
        if (isExecuted) {
          return;
        }
    
        _timer = Timer(Duration(milliseconds: milliseconds), (){
          _timer?.cancel();
          isExecuted = false;
        });
        isExecuted = true;
        action();
      }
    
      void dispose() {
        _timer?.cancel();
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    通过使用Throttler

      // 节流
      final _throttler = Throttler(milliseconds: 5000);
    
      void testThrottler(BuildContext context) {
        _throttler.run(() {
          print("testThrottler time:${DateTime.now()}");
        });
      }
    
      
      void dispose() {
        // TODO: implement dispose
        super.dispose();
        _throttler.dispose();
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    测试结果如下

    testThrottler time:2023-10-16 10:42:41.445236

    在多次点击时候,打印了第一次调用的输出,在5s的连续时间内,后面的点击均被忽略。

    四、使用插件EasyDebounce实现

    当然,也有EasyDebounce可以实现防抖Debounce与节流Throttler

    在pubspec.yaml引入EasyDebounce

    # 防抖与节流
      easy_debounce: ^2.0.3
    
    • 1
    • 2

    实现防抖

    EasyDebounce.debounce('testDebouncer', Duration(milliseconds: 500), () {
      print("EasyDebounce testDebouncer time:${DateTime.now()}");
    });
    
    • 1
    • 2
    • 3

    实现节流

    EasyThrottle.throttle(‘testThrottler’, Duration(milliseconds: 500), () {
    print(“EasyThrottle testThrottler time:KaTeX parse error: Expected 'EOF', got '}' at position 21: …Time.now()}"); }̲, onAfter: (){ …{DateTime.now()}”);
    });

    不需要的时候,在dispose中进行调用

      
      void dispose() {
        // TODO: implement dispose
        super.dispose();
        EasyThrottle.cancelAll();
        EasyDebounce.cancelAll();
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    五、小结

    flutter开发实战-防抖Debounce与节流Throttler实现。可能描述不准确,请见谅。

    https://blog.csdn.net/gloryFlow/article/details/133869893

    学习记录,每天不停进步。

  • 相关阅读:
    Java 大神面试经验
    leetcode 50. Pow(x, n)
    Reference for Ruijie Switch Configuration
    高斯消元
    linux mysql 安装
    2020 CCF-CSP-S-第一轮-C++ 模拟试卷(五)--有答案
    深入了解- TCP拥塞状态机 tcp_fastretrans_alert
    QT DAY7
    四非保研之旅
    成为Linux大神——必须要具备的基本技能!
  • 原文地址:https://blog.csdn.net/gloryFlow/article/details/133869893