Concurrency in Dart -Part III
Concurrency in Action

This article handles a scenario where there is an async function called foo() and it calls another async function bar() multiple times and awaits on it. Now what we want is if I call foo() multiple times then each foo() execution should take place one after the other.
Code snippet:
Output:
entering foo function for value 5Before first bar await for value 5entering foo function for value 10Before first bar await for value 10entering foo function for value 15Before first bar await for value 15entering foo function for value 29Before first bar await for value 29Before second bar await for value 5Before second bar await for value 10Before second bar await for value 15Before second bar await for value 29Before third bar await for value 5Before third bar await for value 10Before third bar await for value 15Before third bar await for value 29Before last bar await for value 5Before last bar await for value 10Before last bar await for value 15Before last bar await for value 2929
Problem: As a programmer, I want that foo() should complete itself before any other foo() calls the first bar() function.
Solution:
Output:
entering foo function for value 1go for value 1Before first bar await for value 1entering foo function for value 2waiting for value 2entering foo function for value 3waiting for value 3entering foo function for value 4waiting for value 4Before second bar await for value 1Before third bar await for value 1Before last bar await for value 1completed foo for value 1unlocked for 2entering foo function for value 2go for value 2Before first bar await for value 2unlocked for 3entering foo function for value 3waiting for value 3unlocked for 4entering foo function for value 4waiting for value 4Before second bar await for value 2Before third bar await for value 2Before last bar await for value 2completed foo for value 2unlocked for 3entering foo function for value 3go for value 3Before first bar await for value 3unlocked for 4entering foo function for value 4waiting for value 4Before second bar await for value 3Before third bar await for value 3Before last bar await for value 3completed foo for value 3unlocked for 4entering foo function for value 4go for value 4Before first bar await for value 4Before second bar await for value 4Before third bar await for value 4Before last bar await for value 4completed foo for value 44
Explanation
We are using a Future<void> isWorking here which only completes at the end of foo(). Any other call to foo() while foo() is working is awaited on isWorking future. To complete the isWorking future we are using Completer which gives us a way to complete the future, once Completer says it is completed, the event queue picks up the first awaited foo() function at line no 9.
Further readings: