提交异步防抖或者节流操作
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