【问题标题】:How can I "sleep" a Dart program我怎样才能“休眠”一个 Dart 程序
【发布时间】:2013-08-29 06:43:42
【问题描述】:

我喜欢在我的 Dart 应用程序中模拟一个异步 Web 服务调用来进行测试。为了模拟这些模拟调用响应的随机性(可能是无序的),我想对我的模拟进行编程,使其在返回“未来”之前等待(睡眠)一段时间。

我该怎么做?

【问题讨论】:

    标签: unit-testing mocking dart


    【解决方案1】:

    2019 年版:

    在异步代码中

    await Future.delayed(Duration(seconds: 1));
    

    在同步代码中

    import 'dart:io';
    
    sleep(Duration(seconds:1));
    

    注意:这会阻塞整个进程(隔离),因此不会处理其他异步函数。它也不能在网络上使用,因为 Javascript 真的是异步的。

    【讨论】:

    • 他们两个有什么区别(sleep vs Future.delayed)?在这两种情况下,幕后发生了什么?
    • sleep() 完全阻止了整个隔离区。 Dart 代码在睡眠时根本不会运行。它可能编译成类似于 C++ 的std::this_thread::sleep_forFuture.delayed() 安排异步函数稍后恢复,但随后它将控制权返回给 Dart 事件循环,以便其他异步函数可以继续运行。
    【解决方案2】:

    您还可以使用 Future.delayed 工厂在延迟后完成未来。下面是两个函数在延迟后异步返回字符串的示例:

    import 'dart:async';
    
    Future sleep1() {
      return new Future.delayed(const Duration(seconds: 1), () => "1");
    }
    
    Future sleep2() {
      return new Future.delayed(const Duration(seconds: 2), () => "2");
    }
    

    【讨论】:

    • () => "1" 的目的是什么?
    • 我猜没用,它只是一个占位符来做你的计算
    • 要让你的应用使用这些函数休眠,你需要使用 await:await sleep1();
    【解决方案3】:

    它并不总是你想要的(有时你想要Future.delayed),但如果你真的想在你的 Dart 命令行应用程序中睡觉,你可以使用 dart:io 的sleep()

    import 'dart:io';
    
    main() {
      sleep(const Duration(seconds:1));
    }
    

    【讨论】:

    • 好!不幸的是,在官方网站上很难找到这些信息。
    • 'dart:io' 库在构建 Web 应用程序时不可用
    • 来自文档:请谨慎使用,因为在 [sleep] 调用中阻塞时,无法在隔离中处理异步操作
    • 警告:这是同步的!!!它将停止主线程! (我很傻,我做了await sleep() 并期望其他工作在睡眠期间运行:(
    • 他们两个有什么区别(sleep vs Future.delayed)?在这两种情况下,幕后发生了什么?
    【解决方案4】:

    我发现Dart中有几种实现可以让代码延迟执行:

    new Future.delayed(const Duration(seconds: 1)); //recommend
    
    new Timer(const Duration(seconds: 1), ()=>print("1 second later."));
    
    sleep(const Duration(seconds: 1)); //import 'dart:io';
    
    new Stream.periodic(const Duration(seconds: 1), (_) => print("1 second later.")).first.then((_)=>print("Also 1 second later."));
    //new Stream.periodic(const Duration(seconds: 1)).first.then((_)=>print("Also 1 second later."));
    

    【讨论】:

      【解决方案5】:

      对于 Dart 2+ 语法,在异步函数上下文中:

      import 'package:meta/meta.dart'; //for @required annotation
      
      void main() async {
        void justWait({@required int numberOfSeconds}) async {
          await Future.delayed(Duration(seconds: numberOfSeconds));
        }
      
        await justWait(numberOfSeconds: 5);
      } 
      

      【讨论】:

        【解决方案6】:

        这是一个有用的模拟,可以带一个可选参数来模拟错误:

          Future _mockService([dynamic error]) {
            return new Future.delayed(const Duration(seconds: 2), () {
              if (error != null) {
                throw error;
              }
            });
          }
        

        你可以这样使用它:

          await _mockService(new Exception('network error'));
        

        【讨论】:

          猜你喜欢
          • 2021-01-18
          • 1970-01-01
          • 2014-06-20
          • 2011-02-06
          • 2020-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多