A Completer creates Future objects that can be completed later. The Completer.future that's set in the getNumber method is the Future that will be completed once complete is called.
In the example in this recipe, when you call the getNumber() method, you are returning a Future, by calling the following:
return completer.future;
The getNumber() method also calls the calculate() async function, which waits 5 seconds (here, you could place any long-running task), and calls the completer.complete method.
Completer.complete changes the state of the Completer, so that you can get the returned value in a then() callback.
Completers are very useful when you call a service that does not use Futures, and you want to return a Future. It also de-couples the execution of your long-running task from the Future itself.