Question

It's my first program in Dart, and I just wanted to see it's asynchronous capabilities. Knowing javascript I wrote the following code:

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()));
}

and the output on the dart editor is:

Fib1:165580141
Fib2:165580141
Fib3:165580141

All 3 outputs are printed at the same time. Isn't that wrong? fib3 is much faster and should be printed first.

Was it helpful?

Solution

Running asynchronous doesn't mean multithreaded. Dart runs singlethreaded. You can spawn isolates to run code in parallel.

When you add a print statement

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

after your three Timer.run(... statements you get a glimpse what async is about.

The closure you provide with Timer.run(...) gets scheduled for later execution and the next statement of your main is executed. As soon as the event loop has time to process scheduled tasks your closures are executed one by one.

You can find more in-depth information here: The Event Loop and Dart

** EDIT **

When you run it this way the output may make more sense for you

  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');

** output **

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

It's not the case that the faster task ends first. Timer.run() schedules for later execution and the execution of main() continues. When the event loop get's back the control of the program flow it executes the scheduled tasks one at a time and one after the other.

Maybe the output is buffered somehow by DartEditor output window or shell and shown in batches. This may lead to the impression that the results are printed all at once.

** EDIT 2 **

I just saw that the results are written one by one. It's easy to verify if you move the slow Fib1 at the last position (after Fib3)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top