dart 如果多次请求,如何忽略先前请求的API

falq053o  于 2024-01-03  发布在  其他
关注(0)|答案(5)|浏览(103)

我在Flutter应用程序中使用HTTP请求来处理API。我实现了API来搜索产品,一旦得到响应,它就会显示在我的UI上。我的问题是请求的API将在不同的时间返回,这意味着如果我搜索“sweets”,如果我输入“s ",它将启动一个搜索”s“的API请求,输入”so“后,它将发送另一个API调用,但是“SW”响应可能首先来自服务器,然后才到达“% s”结果。它将取代我需要在应用程序中显示的确切结果。如何防止此问题?

gywdnpxw

gywdnpxw1#

有一个叫做debounce的概念,它只是意味着它可以等待特定的时间来触发回调。
在Dart中还有另一个可调用类的概念,你可以使用它们来消除抖动:

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

dxxyhpgq

dxxyhpgq2#

例如,如果传入的响应是“sw”,而用户已经输入了“sw”,则将其标记为布尔值“true”,并忽略后续的响应;或者,如果传入的响应是“s”,但用户已经输入了“sw”,则将其布尔值标记为“false”,并忽略它,不要让它替换先前的数据。
你可以在你的对象模型中定义这个布尔值。

eni9jsuy

eni9jsuy3#

我的理解是,你有一个文本字段,你试图在onChanged函数中调用一个API,你希望在输入新字符之前给用户给予一些时间来查看结果。你有两个选择:
1.使用定时器,延迟呼叫几秒钟,对每一个电话。
1.使用TextEditingController而不是依赖onChanged。然后在onSubmitted函数中调用API。

yrwegjxp

yrwegjxp4#

您可以为每个API调用使用唯一的标志。这些标志可以在本地缓存,并在进行另一个API调用之前检查标志是否存在。

imzjd6km

imzjd6km5#

下面是使用AutoComplete Widget示例

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
}


对不起,我的英语不好,但希望能帮助您的问题

相关问题