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

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

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

一、防抖Debounce与节流Throttler

  • 防抖Debounce

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

  • 节流Throttler

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

二、实现防抖

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

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

dart 复制代码
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();
  }
}

通过使用Debouncer

dart 复制代码
// 防抖
  final _debouncer = Debouncer(milliseconds: 5000);


  void testDebouncer(BuildContext context) {
    _debouncer.run(() {
      print("testDebouncer time:${DateTime.now()}");
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _debouncer.dispose();
  }

测试结果如下

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

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

三、实现节流

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

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

dart 复制代码
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();
  }
}

通过使用Throttler

dart 复制代码
  // 节流
  final _throttler = Throttler(milliseconds: 5000);

  void testThrottler(BuildContext context) {
    _throttler.run(() {
      print("testThrottler time:${DateTime.now()}");
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _throttler.dispose();
  }

测试结果如下

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

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

四、使用插件EasyDebounce实现

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

在pubspec.yaml引入EasyDebounce

dart 复制代码
# 防抖与节流
  easy_debounce: ^2.0.3

实现防抖

dart 复制代码
EasyDebounce.debounce('testDebouncer', Duration(milliseconds: 500), () {
  print("EasyDebounce testDebouncer time:${DateTime.now()}");
});

实现节流

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中进行调用

dart 复制代码
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    EasyThrottle.cancelAll();
    EasyDebounce.cancelAll();
  }

五、小结

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

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

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

相关推荐
程序员老刘14 分钟前
跨平台开发地图 | 2026年9月
flutter·客户端
nvvas35 分钟前
Java 入门(四):数组——数据的集合管理
java·开发语言
默_笙36 分钟前
🚋 从流水线到地铁网:为什么复杂 AI 都要拆成多 Agent(上)——LangGraph 基础入门
前端·javascript
ID34610744201 小时前
【课程设计】基于Spring Boot+Vue的游戏账号租赁系统的设计与实现-计算机毕设 附源码50345
javascript·vue.js·spring boot·python·node.js·php·课程设计
柚yuzumi1 小时前
彻底搞懂 JavaScript 类型转换:显式转换、隐式转换与 ToPrimitive
前端·javascript·node.js
Y3815326621 小时前
SERP 数据清洗实战:字段标准化、日期解析与去重键
开发语言·数据库·python·python数据库
君顾12 小时前
本地城市低空经济管理系统定制:城市级低空运营平台架构与落地实战
java·开发语言·飞手
多多鼠3 小时前
System Prompt 的“版本漂移”问题:从变更管理到 A/B 测试体系
开发语言·网络·人工智能·python·langchain
AI情绪识别开源3 小时前
检信ALLEMOTION 认知评估分析器 · WebSocket 推送数据文档
javascript
WiChP3 小时前
【V0.1B16】从零开始的2D游戏引擎开发之路
开发语言·算法·游戏引擎