在特定时间等待未来
Await future for a specific time
您将如何在特定时间内等待未来的响应?
比如说,我们发出一个 http post 请求并在我们关闭 http 请求之前等待它的响应,但是,我们只等待 3 秒,否则我们关闭请求。
您将如何实现?
类似
Future makePostReq() async{
....
await http response for 3 secs
....
if(response) {
... Do something with it
}
Http.close
}
您可以使用 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));
你可以很容易做到
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';
Future.any([asyncfunc, ...])
这是使用 Remi 的 Future.any
解决方案的示例,其中将首先使用 returns 的未来。另一个被丢弃。
因此,第一个 future 是您的 data-gathering/slow 函数,另一个是当您的调用时间过长时的回退。
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 页面的 copy/paste 示例:
(查看消息的 debug/run 输出 window)
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);
}
}
您将如何在特定时间内等待未来的响应?
比如说,我们发出一个 http post 请求并在我们关闭 http 请求之前等待它的响应,但是,我们只等待 3 秒,否则我们关闭请求。
您将如何实现?
类似
Future makePostReq() async{
....
await http response for 3 secs
....
if(response) {
... Do something with it
}
Http.close
}
您可以使用 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));
你可以很容易做到
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';
Future.any([asyncfunc, ...])
这是使用 Remi 的 Future.any
解决方案的示例,其中将首先使用 returns 的未来。另一个被丢弃。
因此,第一个 future 是您的 data-gathering/slow 函数,另一个是当您的调用时间过长时的回退。
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 页面的 copy/paste 示例:
(查看消息的 debug/run 输出 window)
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);
}
}