2

这是我在 Dart 中的第一个程序,我只是想看看它的异步功能。知道 javascript 我写了以下代码:

import 'dart:async' show Timer;
import 'dart:math';

void main() {
  //Recursion
  fib1(x) => x > 1 ? fib1(x-1) + fib1(x-2) : x;
  //Mathematical
  num fi = (1 + sqrt(5)) / 2;
  fib2(x) => x > 1 ? ((pow(fi, x) + pow(1 - fi, x)) / sqrt(5)).round() : x;
  //Linear
  fib3(x) {
    if(x < 2) return x;
    int a1  = 0;
    int a2  = 1;
    int sum = 0;
    for(int i = 1; i < x; i++) {
      sum = a2 + a1;
      a1 = a2;
      a2 = sum;
    }

    return sum;
  }

  Timer.run(() => print('Fib1:' + fib1(41).toString()));
  Timer.run(() => print('Fib2:' + fib2(41).toString()));
  Timer.run(() => print('Fib3:' + fib3(41).toString()));
}

飞镖编辑器上的输出是:

Fib1:165580141
Fib2:165580141
Fib3:165580141

同时打印所有 3 个输出。那不是错了吗?fib3 要快得多,应该先打印。

4

1 回答 1

4

运行异步并不意味着多线程。Dart 运行单线程。您可以生成隔离以并行运行代码。

添加打印语句时

{
  //...
  Timer.run(() => print('Fib1:' + fib1(41).toString()));
  Timer.run(() => print('Fib2:' + fib2(41).toString()));
  Timer.run(() => print('Fib3:' + fib3(41).toString()));
  print('exit');
}

在您的三个Timer.run(...陈述之后,您可以一瞥异步是什么。

您提供的闭包Timer.run(...)被安排在以后执行,并执行 main 的下一条语句。一旦事件循环有时间处理计划任务,您的闭包就会被一一执行。

您可以在此处找到更深入的信息:事件循环和 Dart

** 编辑 **

当你以这种方式运行它时,输出可能对你更有意义

  Timer.run(() => print('Fib1: ${new DateTime.now()} - result: ${fib1(41)}'));
  Timer.run(() => print('Fib2: ${new DateTime.now()} - result: ${fib2(41)}'));
  Timer.run(() => print('Fib3: ${new DateTime.now()} - result: ${fib3(41)}'));
  print('exit');

** 输出 **

exit
Fib1: 2014-01-07 12:00:46.953 - result: 165580141
Fib2: 2014-01-07 12:00:56.208 - result: 165580141
Fib3: 2014-01-07 12:00:56.210 - result: 165580141

不是更快的任务首先结束。Timer.run()安排以后执行和main()继续执行。当事件循环重新获得对程序流的控制权时,它一次一个地执行计划任务,一个接一个地执行。

也许输出被 DartEditor 输出窗口或 shell 以某种方式缓冲并分批显示。这可能会导致结果被一次性打印出来的印象。

** 编辑 2 **

刚才看到结果是一一写出来的。很容易验证您是否将慢速移动到Fib1最后一个位置(之后Fib3

于 2014-01-07T10:01:30.540 回答