Search code examples
dartdart-async

Future sequence


In the following code I thought the f1 > f2 > f3 would be the invocation order, but only f1 is being invoked. How can I get the 3 functions to be invoked sequentially?

I have added the following to the main function and it works as expected but I want to know if there are other definitive ways of achieving the same results?

print('Starting main');
List<Future> futures=new List<Future>();
Future v1=f1();
Future v2=f2();
Future v3=f3();
futures.add(v1);
futures.add(v2);
futures.add(v3);
Future.wait(futures);
print('Leaving main');

import 'dart:async';

Duration d1 = new Duration(seconds: 5);
Duration d2 = new Duration(seconds: 10);
Duration d3 = new Duration(seconds: 15);

bool r1 = false;
bool r2 = false;
bool r3 = false;

void cb1() {
    print('Entering CB1');
    r1 = true;
    print('Leaving CB1');
}

void cb2() {
    print('Entering CB2');
    r2 = true;
    print('Leaving CB2');
}

void cb3() {
    print('Entering CB3');
    r3 = true;
    print('Leaving CB3');
}

Timer t1;
Timer t2;
Timer t3;

Future<bool> start1() {
    print('Entering start1');
    Completer<bool> r = new Completer();
    r.future.then((_) {
        while (!r1) {

        }
        print('Completing start1');
        r.complete(true);
    });

    print('Leaving start1');
    return r.future;
}

Future<bool> start2() {
    print('Entering start2');
    Completer<bool> r = new Completer();
    r.future.then((_) {
        while (!r2) {

        }
        print('Completing start2');
        r.complete(true);
    });

    print('Leaving start2');
    return r.future;
}

Future<bool> start3() {
    print('Entering start3');
    Completer<bool> r = new Completer();
    r.future.then((_) {
        while (!r3) {

        }
        print('Completing start3');
        r.complete(true);
    });

    print('Leaving start3');
    return r.future;
}

Future<bool> f1() {
    print('Entering f1');
    Completer<bool> result = new Completer();
    t1 = new Timer(d1, cb1);
    result.complete(start1());

    print('Leaving f1');
    return result.future;
}

Future<bool> f2() {
    print('Entering f2');
    Completer<bool> result = new Completer();
    t2 = new Timer(d2, cb2);
    result.complete(start2());

    print('Leaving f2');
    return result.future;
}

Future<bool> f3() {
    print('Entering f3');
    Completer<bool> result = new Completer();
    t3 = new Timer(d3, cb3);
    result.complete(start3());

    print('Leaving f3');
    return result.future;
}

void main() {
    print('Starting main');
    f1().then((_) {
        f2().then((_) {
            f3().then((_) {

            });
        });
    });
    print('Leaving main');
}

Solution

  • First of all you should clarify why you need this. I don't really get why you want them to be executed sequentially - you should give us some more information on the concept behind it.

    Please give us some more information on what you want to accomplish! The following code does somehow what I think you want:

    // I did some more cleanup to the code:

    import 'dart:async';
    
    Duration d1 = new Duration(seconds: 5);
    Duration d2 = new Duration(seconds: 10);
    Duration d3 = new Duration(seconds: 15);
    
    Future<bool> f1() {
      print('Entering f1');
      Completer<bool> r = new Completer();
      new Timer(d1, () {
        r.complete(true);
      });
      print('Leaving f1');
      return r.future;
    }
    
    Future<bool> f2() {
      print('Entering f2');
      Completer<bool> r = new Completer();
      new Timer(d2, () {
        r.complete(true);
      });
      print('Leaving f2');
      return r.future;
    }
    
    Future<bool> f3() {
      print('Entering f3');
      Completer<bool> r = new Completer();
      new Timer(d3, () {
        r.complete(true);
      });
      print('Leaving f3');
      return r.future;
    }
    
    void main() {
        print('Starting main');
        f1().then((_) {
            f2().then((_) {
                f3().then((_) {
    
                });
            });
        });
        print('Leaving main');
    }