有没有办法取消dart的未来?
在Dart UI中,我有一个按钮[submit]来启动一个长异步请求。[submit]处理程序返回未来。接下来,按钮[submit]被按钮[cancel]替换,以允许取消整个操作。在[cancel]处理程序中,我想取消长操作。如何取消提交处理程序返回的未来?就我所知,没有办法取消未来。但是有一种方法可以取消流订阅,也许这可以帮助您 在按钮上调用有没有办法取消dart的未来?,dart,dart-async,Dart,Dart Async,在Dart UI中,我有一个按钮[submit]来启动一个长异步请求。[submit]处理程序返回未来。接下来,按钮[submit]被按钮[cancel]替换,以允许取消整个操作。在[cancel]处理程序中,我想取消长操作。如何取消提交处理程序返回的未来?就我所知,没有办法取消未来。但是有一种方法可以取消流订阅,也许这可以帮助您 在按钮上调用onSubmit,将返回StreamSubscription对象。您可以显式存储该对象,然后对其调用cancel(),以取消流订阅: StreamSubs
onSubmit
,将返回StreamSubscription
对象。您可以显式存储该对象,然后对其调用cancel()
,以取消流订阅:
StreamSubscription=somedElement.onSubmit.listen((数据){
//你在这里编码
if(someCondition==true){
订阅。取消();
}
});
稍后,作为对某些用户操作的响应,您可能可以取消订阅:将未来的任务从“做某事”更改为“做某事,除非已取消”。实现这一点的一个明显方法是设置一个布尔标志,并在将来的闭包中检查它,然后再开始处理,也许在处理过程中的几个点上检查
此外,这似乎有点像黑客,但将未来的超时设置为零似乎会有效地取消未来。我实现“取消”计划执行的一种方法是使用
计时器。在这种情况下,我实际上是在推迟
runMultipleTimes()
方法将按顺序多次调用,但只有在批处理1秒后,才会执行批处理内的。您可以使用或取消将来的操作。请参见以下两个版本:
解决方案1:CancelableOperation
(包含在测试中,您可以自己尝试):
- 取消未来
- 取消流
上述两项测试都将输出:
then: future result
onDone
onCancel
现在,如果我们取消注释cancelableoperation.cancel()代码>则上述两个测试都将输出:
then: future result
onDone
onCancel
解决方案2:CancelableCompleter
(如果需要更多控制)
输出:
isCanceled: false
isCompleted: true
then: future result
onDone
现在,如果我们取消注释cancelableoperation.cancel()代码>我们得到输出:
onCancel
isCanceled: true
isCompleted: true
请注意,如果使用wait cancelableoperation.value
或wait completer.operation
则未来将永远不会返回结果,如果操作被取消,它将无限期地等待。这是因为等待CancelableOperation.value
与写入CancelableOperation.value相同。然后(…)
但是如果操作被取消,将永远不会调用然后()
记得添加省道包。
对于那些试图在颤振中实现这一点的人,这里有一个简单的例子
class MyPage extends StatelessWidget {
final CancelableCompleter<bool> _completer = CancelableCompleter(onCancel: () => false);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Future")),
body: Column(
children: <Widget>[
RaisedButton(
child: Text("Submit"),
onPressed: () async {
// it is true only if the future got completed
bool _isFutureCompleted = await _submit();
},
),
RaisedButton(child: Text("Cancel"), onPressed: _cancel),
],
),
);
}
Future<bool> _submit() async {
_completer.complete(Future.value(_solve()));
return _completer.operation.value;
}
// This is just a simple method that will finish the future in 5 seconds
Future<bool> _solve() async {
return await Future.delayed(Duration(seconds: 5), () => true);
}
void _cancel() async {
var value = await _completer.operation.cancel();
// if we stopped the future, we get false
assert(value == false);
}
}
类MyPage扩展了无状态小部件{
final CancelableCompleter _completer=CancelableCompleter(onCancel:()=>false);
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(标题:文本(“未来”)),
正文:专栏(
儿童:[
升起的按钮(
儿童:文本(“提交”),
onPressed:()异步{
//只有未来完成了,这才是真的
bool_isFutureCompleted=等待提交();
},
),
RaisedButton(子项:文本(“取消”),按下时:取消),
],
),
);
}
Future\u submit()异步{
_completer.complete(Future.value(_solve());
返回_completer.operation.value;
}
//这只是一个简单的方法,将在5秒钟内完成未来
Future\u solve()异步{
返回等待未来。延迟(持续时间(秒:5),()=>true);
}
void\u cancel()异步{
var value=wait_completer.operation.cancel();
//如果我们停止了未来,我们就会变得虚假
断言(值==false);
}
}
我的2美分价值
class CancelableFuture {
bool cancelled = false;
CancelableFuture(Duration duration, void Function() callback) {
Future<void>.delayed(duration, () {
if (!cancelled) {
callback();
}
});
}
void cancel() {
cancelled = true;
}
}
类可取消未来{
bool取消=假;
CancelableFuture(持续时间,void函数()回调){
未来。延迟(持续时间,(){
如果(!取消){
回调();
}
});
}
作废取消(){
取消=真;
}
}
如何取消未来。延迟
一个简单的方法是使用计时器代替:)
Timer\u定时器;
作废(附表){
_计时器=计时器(持续时间(秒数:2),(){
打印(“延迟后做某事”);
});
}
@凌驾
无效处置(){
super.dispose();
_计时器?.cancel();
}
以下代码有助于设计未来的超时功能,并且可以手动取消
import 'dart:async';
class API {
Completer<bool> _completer;
Timer _timer;
// This function returns 'true' only if timeout >= 5 and
// when cancelOperation() function is not called after this function call.
//
// Returns false otherwise
Future<bool> apiFunctionWithTimeout() async {
_completer = Completer<bool>();
// timeout > time taken to complete _timeConsumingOperation() (5 seconds)
const timeout = 6;
// timeout < time taken to complete _timeConsumingOperation() (5 seconds)
// const timeout = 4;
_timeConsumingOperation().then((response) {
if (_completer.isCompleted == false) {
_timer?.cancel();
_completer.complete(response);
}
});
_timer = Timer(Duration(seconds: timeout), () {
if (_completer.isCompleted == false) {
_completer.complete(false);
}
});
return _completer.future;
}
void cancelOperation() {
_timer?.cancel();
if (_completer.isCompleted == false) {
_completer.complete(false);
}
}
// this can be an HTTP call.
Future<bool> _timeConsumingOperation() async {
return await Future.delayed(Duration(seconds: 5), () => true);
}
}
void main() async {
API api = API();
api.apiFunctionWithTimeout().then((response) {
// prints 'true' if the function is not timed out or canceled, otherwise it prints false
print(response);
});
// manual cancellation. Uncomment the below line to cancel the operation.
//api.cancelOperation();
}
导入'dart:async';
类API{
完成者(Completer);;
定时器(u定时器),;
//仅当超时>=5且
//在此函数调用之后未调用cancelOperation()函数时。
//
//否则返回false
Future apiFunctionWithTimeout()异步{
_completer=completer();
//超时>完成_timeConsumingOperation()所用的时间(5秒)
常数超时=6;
//超时<完成\u timeConsumingOperation()所用的时间(5秒)
//常数超时=4;
_timeConsumingOperation()。然后((响应){
如果(_completer.isCompleted==false){
_计时器?.cancel();
_完成者。完成(应答);
}
});
_计时器=计时器(持续时间(秒:超时),(){
如果(_completer.isCompleted==false){
_完成符。完成(假);
}
});
返回_completer.future;
}
作废取消操作(){
_计时器?.cancel();
如果(_completer.isCompleted==false){
_完成符。完成(假);
}
}
//这可以是HTTP调用。
Future\u timeConsumingOperation()异步{
返回等待未来。延迟(持续时间(秒:5),()=>true);
}
}
void main()异步{
API=API();
api.apiFunctionWithTimeout().then((响应){
//印刷品
class CancelableFuture {
bool cancelled = false;
CancelableFuture(Duration duration, void Function() callback) {
Future<void>.delayed(duration, () {
if (!cancelled) {
callback();
}
});
}
void cancel() {
cancelled = true;
}
}
import 'dart:async';
class API {
Completer<bool> _completer;
Timer _timer;
// This function returns 'true' only if timeout >= 5 and
// when cancelOperation() function is not called after this function call.
//
// Returns false otherwise
Future<bool> apiFunctionWithTimeout() async {
_completer = Completer<bool>();
// timeout > time taken to complete _timeConsumingOperation() (5 seconds)
const timeout = 6;
// timeout < time taken to complete _timeConsumingOperation() (5 seconds)
// const timeout = 4;
_timeConsumingOperation().then((response) {
if (_completer.isCompleted == false) {
_timer?.cancel();
_completer.complete(response);
}
});
_timer = Timer(Duration(seconds: timeout), () {
if (_completer.isCompleted == false) {
_completer.complete(false);
}
});
return _completer.future;
}
void cancelOperation() {
_timer?.cancel();
if (_completer.isCompleted == false) {
_completer.complete(false);
}
}
// this can be an HTTP call.
Future<bool> _timeConsumingOperation() async {
return await Future.delayed(Duration(seconds: 5), () => true);
}
}
void main() async {
API api = API();
api.apiFunctionWithTimeout().then((response) {
// prints 'true' if the function is not timed out or canceled, otherwise it prints false
print(response);
});
// manual cancellation. Uncomment the below line to cancel the operation.
//api.cancelOperation();
}