Search code examples
dartasynchronousstreamqueuefuture

Return synchronously called Futures asynchronously in order of execution in queue in Dart


void main() async {
  Future<void> asyncFunction(time, value) async {
    return await Future.delayed(Duration(seconds: time), () => print(value));
  }

  print('1');
  asyncFunction(2, "A");
  asyncFunction(1, "B");
  asyncFunction(0, "C");
  print('2');
}

As per the code above, I'm trying to get the code to print as:

1
2
A
B
C

I want to execute all the functions synchronously and send the asyncFunctions (Futures) off to a sort of queue that then executes those in the order they are recieved. Each function must wait for the previous function to complete it's Future before it then itself executes.

I've been trying around with streams but not getting it right.


Solution

  • If you want an asynchronous queue of tasks where each new task added is delayed until the previous one has completed, you can write one yourself.

    class AsyncQueue<T> {
      Future<T?> _current = Future.value(null);
      Future<T> add(FutureOr<T> Function() task) {
        FutureOr<T> wrapper(void _) => task();
        return _current = _current.then(wrapper, onError: wrapper);
      }
    }
    

    which you can use as:

    Future<void> asyncFunction(time, value) async {
      await Future.delayed(Duration(seconds: time), () => print(value));
    }
    ...
      var queue = AsyncQueue<void>();
      print("1");
      var f1 = queue.add(() => asyncFunction(2, "A"));
      var f2 = queue.add(() => asyncFunction(1, "B"));
      var f3 = queue.add(() => asyncFunction(0, "C"));
      print("2");
      await f3;