等待未来的特定时间

时间:2018-10-05 19:25:58

标签: asynchronous dart async-await flutter future

您将如何等待特定时间的将来响应?

说,我们发出一个http发布请求,并在关闭http请求之前等待其响应,但是,我们只等待3秒钟,否则我们关闭了请求。

您将如何实现?

类似

Future makePostReq() async{
  .... 

  await http response for 3 secs

  .... 

 if(response) {
  ... Do something with it
 }

 Http.close

} 

3 个答案:

答案 0 :(得分:7)

您可以轻松完成

try {
       var response = await Http.get("YourUrl").timeout(const Duration(seconds: 3));
       if(response.statusCode == 200){
          print("Success");
       }else{
          print("Something wrong");
       }
 } on TimeoutException catch (e) {
     print('Timeout');
 } on Error catch (e) {
     print('Error: $e');
 }

此示例将超时设置为3秒。如果已经3秒钟没有收到响应,它将抛出TimeoutException

导入此:

import 'package:http/http.dart' as Http;
import 'dart:async';

答案 1 :(得分:3)

您可以使用Future.any构造函数来创建竞争条件

final result = await Future.any([
  Future.value(42),
  Future.delayed(const Duration(seconds: 3))
]);

您还可以使用Future.timout方法

final result = await Future.value(42).timeout(const Duration(seconds: 3));

答案 2 :(得分:2)

Future.any([asyncfunc, ...])

以下是使用 Remi 的 Future.any 解决方案的示例,其中将使用首先返回的未来。另一个被丢弃。

因此,第一个未来是您的数据收集/慢速功能,另一个是当您的通话时间过长时的回退。

    dynamic result = await Future.any([
      getData(fakeDelay: seconds), // ← hope this returns first
      timeoutAfter(sec: timeout, onTimeout: () => 'Timed Out!', ) // ← waited too long, do this
    ]);

Flutter 页面中的示例

以下是 Flutter 页面的复制/粘贴示例:

(查看您的调试/运行输出窗口以获取消息)

import 'package:flutter/material.dart';

class FutureTimeoutPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Future or Timeout Page'),
      ),
      body: FutureAnyExample(),
    );
  }
}

class FutureAnyExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('Complete before timeout or timeout:'),
        SizedBox(height: 30,),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            ElevatedButton(onPressed: () => getDataOrTimeout(seconds: 1, timeout: 3),
                child: Text('In Time')),
            ElevatedButton(onPressed: () => getDataOrTimeout(seconds: 5, timeout: 3),
                child: Text('Too Slow'))
          ],
        )
      ],
    );
  }

  Future<void> getDataOrTimeout({int seconds, int timeout}) async {
    /// In Future.any, put as many async functions as you need.
    /// Whichever completes first, will be returned. All others are discarded
    dynamic result = await Future.any([
      getData(fakeDelay: seconds), // ← hope this returns first
      timeoutAfter(sec: timeout, onTimeout: () => 'Timed Out!', ) // ← waited too long, do this
    ]);

    print(result);
  }

  /// Mock of a long-running operation like getting DB data, or API call
  Future<String> getData({int fakeDelay}) async {
    return Future.delayed(Duration(seconds: fakeDelay), () => 'Data returned!');
  }

  /// Do this in case my long-running op takes too long
  /// Can run a function or just return some message
  Future<dynamic> timeoutAfter({int sec, Function() onTimeout}) async {
    return Future.delayed(Duration(seconds: sec), onTimeout);
  }
}