在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{ final list _items = list .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
取消前一个还未完成的动作,并重新开始计时。 - 只有在延迟时间过去且没有新的调用时,最后一次动作才会执行。
这种方法可以有效地限制事件(如用户输入、按钮点击等)的处理频率,从而优化性能和资源利用。在实际应用中,大家可能需要根据具体情况调整延迟时间和处理逻辑。