当文本框改变时,调用API - 如何进行节流处理?

5

如果我有一个文本框,并且在该文本框中更改时,我调用一个函数,该函数调用一个API,如何进行节流,以便仅在用户没有输入任何内容的情况下才调用该函数1秒钟?

我在这里迷失了..任何帮助都将不胜感激。

2个回答

18

使用Timer

如果在1秒钟内按下键,则取消旧计时器并使用新计时器重新安排,否则进行API调用:

import 'dart:async';

class _MyHomePageState extends State<MyHomePage> {
  String textValue;
  Timer timeHandle;

  void textChanged(String val) {
    textValue = val;
    if (timeHandle != null) {
      timeHandle.cancel();
    }  
    timeHandle = Timer(Duration(seconds: 1), () {
      print("Calling now the API: $textValue");
    });
  }

  @override
  void dispose() {
      super.dispose();
      timeHandle.cancel();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
              padding: EdgeInsets.all(20),
              alignment: Alignment.center,
              child: TextField(
                onChanged: textChanged,
                  decoration: InputDecoration(
                      border: InputBorder.none,
                      hintText: 'Please enter a search term')),
            ),
          ],
        ),
      ),
    );
  }
}

你在dispose()中忘记了null检查,如果onChanged()未被调用的话。不管怎样都非常好用!谢谢。 - Csaba Gergely

2
你需要使用来自async包CancelableOperation类。你可以在你的有状态小部件中声明它,放在build()方法之外:
CancelableOperation cancelableOperation;

onChanged回调中使用它的方式如下:

最初的回答:

cancelableOperation?.cancel();

cancelableOperation = CancelableOperation.fromFuture(Future.delayed(Duration(seconds: 1), () {
  // API call here
}));

2
请注意,使用这种方法后,经过一秒钟后,API调用会被多次调用。这是因为“cancel”方法是异步的。 - attdona

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接