提交异步防抖或者节流操作
This commit is contained in:
commit
c184721f06
|
|
@ -0,0 +1,31 @@
|
|||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
migrate_working_dir/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||
/pubspec.lock
|
||||
**/doc/api/
|
||||
.dart_tool/
|
||||
.flutter-plugins-dependencies
|
||||
/build/
|
||||
/coverage/
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "ac4e799d237041cf905519190471f657b657155a"
|
||||
channel: "stable"
|
||||
|
||||
project_type: package
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
## 0.0.1
|
||||
|
||||
* TODO: Describe initial release.
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<!--
|
||||
This README describes the package. If you publish this package to pub.dev,
|
||||
this README's contents appear on the landing page for your package.
|
||||
|
||||
For information about how to write a good package README, see the guide for
|
||||
[writing package pages](https://dart.dev/tools/pub/writing-package-pages).
|
||||
|
||||
For general information about developing packages, see the Dart guide for
|
||||
[creating packages](https://dart.dev/guides/libraries/create-packages)
|
||||
and the Flutter guide for
|
||||
[developing packages and plugins](https://flutter.dev/to/develop-packages).
|
||||
-->
|
||||
|
||||
TODO: Put a short description of the package here that helps potential users
|
||||
know whether this package might be useful for them.
|
||||
|
||||
## Features
|
||||
|
||||
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
||||
|
||||
## Getting started
|
||||
|
||||
TODO: List prerequisites and provide or point to information on how to
|
||||
start using the package.
|
||||
|
||||
## Usage
|
||||
|
||||
TODO: Include short and useful examples for package users. Add longer examples
|
||||
to `/example` folder.
|
||||
|
||||
```dart
|
||||
const like = 'sample';
|
||||
```
|
||||
|
||||
## Additional information
|
||||
|
||||
TODO: Tell users more about the package: where to find more information, how to
|
||||
contribute to the package, how to file issues, what response they can expect
|
||||
from the package authors, and more.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
import 'package:easy_debounce/easy_debounce.dart';
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
|
||||
/// 异步防抖/节流工具类
|
||||
class AsyncThrottle {
|
||||
// 私有构造函数,防止外部实例化
|
||||
AsyncThrottle._();
|
||||
|
||||
// 懒汉式单例 - 使用 late final 延迟初始化
|
||||
static final AsyncThrottle _instance = AsyncThrottle._();
|
||||
|
||||
// 获取单例实例
|
||||
static AsyncThrottle get instance => _instance;
|
||||
|
||||
// 存储异步任务锁状态
|
||||
final Map<String, bool> _asyncLocks = {};
|
||||
|
||||
/// 异步执行方法 - 防止弱网重复点击 (无 Loading UI)
|
||||
///
|
||||
/// 结合了 时间策略(防抖/节流)和 异步任务状态锁。
|
||||
/// 只有当满足以下两个条件时才会执行:
|
||||
/// 1. 当前没有正在执行的同名任务 (Task Lock - 解决弱网长耗时问题)
|
||||
/// 2. 满足时间策略 (Time Policy - 解决快速连点问题)
|
||||
///
|
||||
/// [tagId]: 唯一标识符
|
||||
/// [onExecute]: 要执行的异步方法
|
||||
/// [duration]: 时间间隔,默认 300ms
|
||||
/// [enableDebounce]: 是否启用防抖模式。
|
||||
/// - true: 使用防抖 (Debounce) - 延迟执行,最后一次点击生效(适合搜索、输入)
|
||||
/// - false: 使用节流 (Throttle) - 立即执行,忽略后续点击(默认,适合按钮点击)
|
||||
Future<void> execute(
|
||||
String tagId,
|
||||
Future<void> Function() onExecute, {
|
||||
Duration duration = const Duration(milliseconds: 300),
|
||||
bool enableDebounce = false,
|
||||
}) async {
|
||||
// 1. 检查异步锁 (防止上一个请求未回来时重复点击)
|
||||
// 无论是防抖还是节流,只要任务还在执行中,都不应重入
|
||||
if (isExecuting(tagId)) return;
|
||||
|
||||
if (enableDebounce) {
|
||||
// === 防抖模式 (Debounce) ===
|
||||
// 延迟 duration 后执行,如果在期间再次调用,会重新计时
|
||||
EasyDebounce.debounce(tagId, duration, () async {
|
||||
// 防抖触发时,再次检查锁(双重检查)
|
||||
if (isExecuting(tagId)) return;
|
||||
|
||||
_asyncLocks[tagId] = true;
|
||||
try {
|
||||
await onExecute();
|
||||
} finally {
|
||||
_asyncLocks.remove(tagId);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// === 节流模式 (Throttle) - 默认 ===
|
||||
// 立即执行,并在 duration 内忽略后续调用
|
||||
// throttle 返回 true 表示被节流(忽略),false 表示获得了执行权
|
||||
final isThrottled = EasyThrottle.throttle(tagId, duration, () {});
|
||||
|
||||
// 如果被节流了,直接返回
|
||||
if (isThrottled) return;
|
||||
|
||||
// 获得执行权,加锁并执行
|
||||
_asyncLocks[tagId] = true;
|
||||
try {
|
||||
await onExecute();
|
||||
} finally {
|
||||
_asyncLocks.remove(tagId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查任务是否正在执行
|
||||
bool isExecuting(String tagId) => _asyncLocks[tagId] ?? false;
|
||||
|
||||
/// 强制取消所有锁(慎用)
|
||||
void clearAllLocks() => _asyncLocks.clear();
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
library yx_async_throttle_flutter;
|
||||
|
||||
export 'package:yx_async_throttle_flutter/async_throttle.dart';
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
name: yx_async_throttle_flutter
|
||||
description: "A new Flutter package project."
|
||||
version: 0.0.1
|
||||
homepage:
|
||||
|
||||
environment:
|
||||
sdk: ^3.9.2
|
||||
flutter: ">=1.17.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
easy_debounce: ^2.0.3
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^5.0.0
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter packages.
|
||||
flutter:
|
||||
|
||||
# To add assets to your package, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
# - images/a_dot_ham.jpeg
|
||||
#
|
||||
# For details regarding assets in packages, see
|
||||
# https://flutter.dev/to/asset-from-package
|
||||
#
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/to/resolution-aware-images
|
||||
|
||||
# To add custom fonts to your package, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
# "family" key with the font family name, and a "fonts" key with a
|
||||
# list giving the asset and other descriptors for the font. For
|
||||
# example:
|
||||
# fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
# - asset: fonts/TrajanPro_Bold.ttf
|
||||
# weight: 700
|
||||
#
|
||||
# For details regarding fonts in packages, see
|
||||
# https://flutter.dev/to/font-from-package
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:yx_async_throttle_flutter/yx_async_throttle_flutter.dart';
|
||||
|
||||
void main() {
|
||||
test('AsyncThrottle instance check', () {
|
||||
final throttle = AsyncThrottle.instance;
|
||||
expect(throttle, isNotNull);
|
||||
});
|
||||
}
|
||||
Loading…
Reference in New Issue