dart中的Future / Completer行为未异步运行

时间:2016-12-11 07:37:49

标签: dart future

我只是想了解期货的行为。以下是示例代码:

import'dart:async';

main() {

  Future short = shortWait();
  Future medium = mediumWait();
  Future long = longWait();
  long.then((String e)=>print(e));
  medium.then((String e)=> print(e));
  short.then((String e)=> print(e));
  }

  Future<String> longWait() {
  Completer c = new Completer<String>();
  for (int i=0; i<100000000; i++);   // creating long latency
  c.complete("long");
  return c.future;
  }
  Future<String> mediumWait() {
    Completer c = new Completer<String>();
    for (int i=0; i<10000; i++);    // creating medium length latency
    c.complete("medium");
    return c.future;
  }
  Future<String> shortWait() {
    Completer c = new Completer<String>();
    c.complete("short");    // no latency
    return c.future;
  }


// short  
// medium
// long

我注意到了一些事情。首先,代码似乎是同步的,并且最长的延迟函数longWait()正在阻塞。在所有内容都可用之前,输出不会显示,然后一次显示所有内容。我认为它应该首先显示可用的东西,然后在期货变得完整时显示。

其次,显示顺序似乎反映了显示Future short / medium / long = shortWait / mediumWait / longWait()的顺序。即改变那些行的顺序,并相应地改变输出的顺序。无论每种方法的延迟时间有多长,也不会对短/中/长的显示顺序产生任何影响。然后((e)=&gt; print(e))。

我希望代码1)在数据可用时显示输出,2)输出顺序应反映函数的延迟。除了理解期货的基本概念之外,我实际上并没有尝试做任何事情。

2 个答案:

答案 0 :(得分:3)

请记住,Dart中的异步并不意味着并行

在您的示例中,您实际上要做的是将五个任务放在队列中:

  1. 数到100000000
  2. 打印&#39; long&#39;
  3. 数到10000
  4. 打印&#39;
  5. 打印&#39;简短&#39;
  6. 所以他们按顺序执行。

    在Dart中,异步意味着在等待某些事情发生时代码不必被阻止。这通常是核心库提供的功能,例如从文件获取数据或通过网络进行交互 - 由操作系统或浏览器执行的任务。

    想到这一点的一种方法是Dart程序可以并行执行&#39;由操作系统或浏览器完成的东西,但不是自己。

    Dart也可以并行执行代码&#39;等待计时器开火。 E.g:

    import 'dart:async';
    
    main() {
    
       // Long latency
      (new Future.delayed(new Duration(seconds: 5)).then((_) => print('long')));
    
      // Medium latency
      (new Future.delayed(new Duration(seconds: 2)).then((_) => print('medium')));
    
      // Short latency
      (new Future.delayed(new Duration(seconds: 1)).then((_) => print('short')));
    
      print('go');
    }
    

    打印:

    go
    short
    medium
    long
    

答案 1 :(得分:2)

Future<String> longWait() {
  Completer c = new Completer<String>();
  for (int i = 0; i < 100000000; i++); // creating long latency
  c.complete("long");
  return c.future;
}

这不是异步做事。只有在for循环完成后才会返回未来。这使得这个功能同步。

要使其异步,请尝试以下操作:

Future<String> longWait() {
  Completer c = new Completer<String>();

  new Future.delayed(new Duration(seconds: 4), () {
    c.complete('long');
  });

  return c.future;
}

Future<String> mediumWait() {
  Completer c = new Completer<String>();

  new Future.delayed(new Duration(seconds: 2), () {
    c.complete('medium');
  });

  return c.future;
}

Future<String> shortWait() {
  Completer c = new Completer<String>();

  new Future.delayed(new Duration(seconds: 0), () {
    c.complete('short');
  });

  return c.future;
}

理想情况下,您可以完全避免使用Completer,因为Future.delayed会返回未来。

Future<String> longWait() {
  return new Future.delayed(new Duration(seconds: 10), ()=>'long');
}
Future<String> mediumWait() {
  return new Future.delayed(new Duration(seconds: 5), ()=>'medium');
}
Future<String> shortWait() {
  return new Future.delayed(new Duration(seconds: 0), ()=>'short');
}