Flutter 防抖和节流

177 阅读2分钟

防抖

class Debouncer {
  static Timer? _timer;

  /// 防抖 只执行最后一次
  /// delay 延迟时间
  /// action 执行操作
  /// cancelAction 取消操作
  static void run({
    Duration delay = const Duration(milliseconds: 1000),
    required Function action,
    Function? cancelAction,
  }) {
    if (_timer != null) {
      cancelAction?.call();
      _timer?.cancel();
    }
    _timer = Timer(delay, () {
      action.call();
      _timer = null;
    });
  }
}

测试

void main() {
  click();
  click();
  click();
  click();
  click();
  click();
  click();
  click();
  Future.delayed(const Duration(milliseconds: 5000), () {
    click();
  });
}

click() {
  Debouncer.run(action: () {
    print('${DateTime.now()} ---  操作完成');
  }, cancelAction: () {
    print('${DateTime.now()} ---  操作被取消');
  });
}

2024-07-13 01:53:08.063240 --- 操作被取消
2024-07-13 01:53:08.065083 --- 操作被取消 
2024-07-13 01:53:08.065130 --- 操作被取消 
2024-07-13 01:53:08.065164 --- 操作被取消 
2024-07-13 01:53:08.065197 --- 操作被取消 
2024-07-13 01:53:08.065233 --- 操作被取消 
2024-07-13 01:53:08.065264 --- 操作被取消
2024-07-13 01:53:09.070954 --- 操作完成
2024-07-13 01:53:14.071084 --- 操作完成

节流


import 'dart:async';

class Throttle {
  static Timer? _timer;
  static bool _isExecuting = true;

  /// 节流1 (执行两次,第一次和最后一次)
  /// 1000毫秒内点击执行第一次,
  /// 1000毫秒内点击不执行,1000毫秒后点击执行第二次
  static void run(
    Function func, {
    Duration delay = const Duration(milliseconds: 1000),
    Function? repeatCallback,
  }) {
    if (_isExecuting) {
      func.call();
      _isExecuting = false;
      return;
    }
    if (_timer != null) {
      repeatCallback?.call();
      return;
    }
    _timer = Timer(delay, () {
      func.call();
      _timer = null;
    });
  }

  /// 节流2 (执行一次,只执行一次)
  /// 1000毫秒内点击执行第一次,
  /// 点击最后一次之后不再执行
  static void run1(
    Function func, {
    Duration delay = const Duration(milliseconds: 1000),
    Function? repeatCallback,
  }) {
    if (_isExecuting) {
      func.call();
      _isExecuting = false;
      return;
    }
    if (_isExecuting == false) {
      repeatCallback?.call();
      _timer = Timer(delay, () {
        _isExecuting = true;
        _timer = null;
      });
    }
  }
}


节流测试1

void main() {
  click();
  click();
  click();
  click();
  click();
  Future.delayed(const Duration(milliseconds: 2000), () {
    click();
  });
}

void click() {
  Throttle.run1(
    () {
      print('${DateTime.now()} ---  操作被执行');
    },
    repeatCallback: () {
      print('${DateTime.now()} ---  重复点击');
    },
  );
}

2024-07-13 01:55:19.934968 --- 操作被执行
2024-07-13 01:55:19.936779 --- 重复点击 
2024-07-13 01:55:19.938041 --- 重复点击
2024-07-13 01:55:19.938181 --- 重复点击 
2024-07-13 01:55:19.938262 --- 重复点击

2024-07-13 01:55:21.940134 --- 操作被执行



节流测试

void main() {
  click();
  click();
  click();
  click();
  click();
  Future.delayed(const Duration(milliseconds: 2000), () {
    click();
  });
}

void click() {
  Throttle.run(
    () {
      print('${DateTime.now()} ---  操作被执行');
    },
    repeatCallback: () {
      print('${DateTime.now()} ---  重复点击');
    },
  );
}


2024-07-13 01:57:53.276364 --- 操作被执行
2024-07-13 01:57:53.279422 --- 重复点击 
2024-07-13 01:57:53.279462 --- 重复点击 
2024-07-13 01:57:53.279489 --- 重复点击
2024-07-13 01:57:54.281457 --- 操作被执行


2024-07-13 01:57:56.283898 --- 操作被执行