我在Flutter应用程序中使用HTTP请求来处理API。我实现了API来搜索产品,一旦得到响应,它就会显示在我的UI上。我的问题是请求的API将在不同的时间返回,这意味着如果我搜索“sweets”,如果我输入“s ",它将启动一个搜索”s“的API请求,输入”so“后,它将发送另一个API调用,但是“SW”响应可能首先来自服务器,然后才到达“% s”结果。它将取代我需要在应用程序中显示的确切结果。如何防止此问题?
gywdnpxw1#
有一个叫做debounce的概念,它只是意味着它可以等待特定的时间来触发回调。在Dart中还有另一个可调用类的概念,你可以使用它们来消除抖动:
debounce
import 'dart:async'; class Debounce { Duration delay; Timer? _timer; Debounce( this.delay, ); call(void Function() callback) { _timer?.cancel(); _timer = Timer(delay, callback); } dispose() { _timer?.cancel(); } }
字符串用法简单
// 1 - Create a debounce instance final Debounce _debounce = Debounce(Duration(milliseconds: 400)); // 2 - Use it _debounce((){ print('First'); }); _debounce((){ print('Second'); }); _debounce((){ print('Third'); }); // ...after 400ms you'll see "Third"
型对于您的特定示例,重要的是要释放计时器,以防它在释放后使用TextController:
final TextEditingController _controller = TextEditingController(); final Debounce _debounce = Debounce(Duration(milliseconds: 400)); @override void dispose() { _controller.dispose(); _debounce.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return TextField( controller: _controller, onChanged: (String value) { _debounce((){ print('Value is $value'); }); }, ); }
型Source
dxxyhpgq2#
例如,如果传入的响应是“sw”,而用户已经输入了“sw”,则将其标记为布尔值“true”,并忽略后续的响应;或者,如果传入的响应是“s”,但用户已经输入了“sw”,则将其布尔值标记为“false”,并忽略它,不要让它替换先前的数据。你可以在你的对象模型中定义这个布尔值。
eni9jsuy3#
我的理解是,你有一个文本字段,你试图在onChanged函数中调用一个API,你希望在输入新字符之前给用户给予一些时间来查看结果。你有两个选择:1.使用定时器,延迟呼叫几秒钟,对每一个电话。1.使用TextEditingController而不是依赖onChanged。然后在onSubmitted函数中调用API。
yrwegjxp4#
您可以为每个API调用使用唯一的标志。这些标志可以在本地缓存,并在进行另一个API调用之前检查标志是否存在。
imzjd6km5#
下面是使用AutoComplete Widget示例
AutoComplete
class DebounceSearch { final Duration duration; Timer? _timer; DebounceSearch({required this.duration}); Future<List<String>> run(FutureOr<List<String>> Function() action) async { if (null != _timer) _timer?.cancel(); Completer<List<String>> completer = Completer(); _timer = Timer(duration, () async { var result = await action(); completer.complete(result); }); return completer.future; } }
字符串在您的页面上:
final debouncer = DebounceSearch(duration: 300.milliseconds); Autocomplete( /// ... optionsBuilder: (s) async { return await debouncer.run(() async { return await _repo.findAutoComplete(s.text); }); }, /// ... ),
型回购/提供商:
Future<List<String>> findAutoComplete(String s) async { /// call your api here }
型对不起,我的英语不好,但希望能帮助您的问题
5条答案
按热度按时间gywdnpxw1#
有一个叫做
debounce
的概念,它只是意味着它可以等待特定的时间来触发回调。在Dart中还有另一个可调用类的概念,你可以使用它们来消除抖动:
字符串
用法简单
型
对于您的特定示例,重要的是要释放计时器,以防它在释放后使用TextController:
型
Source
dxxyhpgq2#
例如,如果传入的响应是“sw”,而用户已经输入了“sw”,则将其标记为布尔值“true”,并忽略后续的响应;或者,如果传入的响应是“s”,但用户已经输入了“sw”,则将其布尔值标记为“false”,并忽略它,不要让它替换先前的数据。
你可以在你的对象模型中定义这个布尔值。
eni9jsuy3#
我的理解是,你有一个文本字段,你试图在onChanged函数中调用一个API,你希望在输入新字符之前给用户给予一些时间来查看结果。你有两个选择:
1.使用定时器,延迟呼叫几秒钟,对每一个电话。
1.使用TextEditingController而不是依赖onChanged。然后在onSubmitted函数中调用API。
yrwegjxp4#
您可以为每个API调用使用唯一的标志。这些标志可以在本地缓存,并在进行另一个API调用之前检查标志是否存在。
imzjd6km5#
下面是使用
AutoComplete
Widget示例字符串
在您的页面上:
型
回购/提供商:
型
对不起,我的英语不好,但希望能帮助您的问题