Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法取消dart的未来?_Dart_Dart Async - Fatal编程技术网

有没有办法取消dart的未来?

有没有办法取消dart的未来?,dart,dart-async,Dart,Dart Async,在Dart UI中,我有一个按钮[submit]来启动一个长异步请求。[submit]处理程序返回未来。接下来,按钮[submit]被按钮[cancel]替换,以允许取消整个操作。在[cancel]处理程序中,我想取消长操作。如何取消提交处理程序返回的未来?就我所知,没有办法取消未来。但是有一种方法可以取消流订阅,也许这可以帮助您 在按钮上调用onSubmit,将返回StreamSubscription对象。您可以显式存储该对象,然后对其调用cancel(),以取消流订阅: StreamSubs

在Dart UI中,我有一个按钮[submit]来启动一个长异步请求。[submit]处理程序返回未来。接下来,按钮[submit]被按钮[cancel]替换,以允许取消整个操作。在[cancel]处理程序中,我想取消长操作。如何取消提交处理程序返回的未来?就我所知,没有办法取消未来。但是有一种方法可以取消流订阅,也许这可以帮助您

在按钮上调用
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();
}