在Flutter
中,Completer
可以用来实现防抖功能。防抖是用于确保时间内的所有触发被合并成单一请求。对于连续的事件触发(如用户的键盘输入、按钮的连续点击),只有在指定的延迟时间内没有再次触发事件时,才执行实际的操作。
下面是如何使用 Completer
来实现异步防抖的一个示例,代码如下:
import 'dart:async'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Drag to Sort', home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final List<String> _items = List<String>.generate(10, (i) => 'Item $i'); bool _isReorderable = false; @override void initState() { // TODO: implement initState super.initState(); var debouncer = Debouncer(delay: Duration(seconds: 1)); // 模拟快速连续触发事件 debouncer.run(() => print('Action 1')); debouncer.run(() => print('Action 2')); debouncer.run(() => print('Action 3')); // 等待一秒后执行 Future.delayed(Duration(seconds: 2), () { debouncer.run(() => print('Action after delay')); }); } @override Widget build(BuildContext context) { return Scaffold( // backgroundColor: Colors.blueAccent, appBar: AppBar( title: Text('Test'), ), body: Column(children: [ _buildContainer(Colors.lightBlue,const Flexible( child: Text("这是一个项目",maxLines: 1,overflow: TextOverflow.ellipsis,))), _buildContainer(Colors.red, const Flexible( fit: FlexFit.tight, child: Text("这是一个项目",maxLines: 1,overflow: TextOverflow.ellipsis,))), _buildContainer(Colors.purple, Flexible( fit: FlexFit.tight, child: Text("这是一个项目" * 6,maxLines: 1,overflow: TextOverflow.ellipsis,))), _buildContainer(Colors.blue, Expanded( child: Text("这是一个项目" * 6,maxLines: 1,overflow: TextOverflow.ellipsis,))), ],), ); } Container _buildContainer(Color color,Widget child) { return Container( height: 56, color: color, child: Row( children: [ const SizedBox(width:16), const Text("来源:"), child, const SizedBox(width: 8), Container( padding: EdgeInsets.all(5), decoration: const BoxDecoration( color: Colors.cyan, borderRadius: BorderRadius.all(Radius.circular(6)) ), child: Text("项目"), ), const SizedBox(width:16), ], ), ); } } class Debouncer { final Duration delay; Completer? _lastCompleter; Timer? _timer; Debouncer({required this.delay}); void run(Function action) { // 如果之前的操作还没有完成,取消它 if (_lastCompleter != null && !_lastCompleter!.isCompleted) { _lastCompleter!.completeError('Cancelled'); } _lastCompleter = Completer(); // 重置计时器 _timer?.cancel(); _timer = Timer(delay, () { action(); _lastCompleter!.complete(); }); // 处理取消操作 _lastCompleter!.future.catchError((error) { print('操作被取消'); }); } }
打印如下:
在这个示例中:
Debouncer
类包含了防抖逻辑。run
方法接受一个要执行的动作,并且确保在连续调用时,只有最后一次调用会在指定的延迟后执行。- 当
run
方法被连续调用时,它会通过Completer
取消前一个还未完成的动作,并重新开始计时。 - 只有在延迟时间过去且没有新的调用时,最后一次动作才会执行。
这种方法可以有效地限制事件(如用户输入、按钮点击等)的处理频率,从而优化性能和资源利用。在实际应用中,大家可能需要根据具体情况调整延迟时间和处理逻辑。