Based on the documentation, a Future is the result of an asynchronous computation. But what does that mean.

When we call a function or a method, we normally expect it to do something. Usually this is pretty fast, but not always. Sometime computation takes some time. Most of the time this is result of reading something from internet, like downloading a json file, or an image.

Now if you are building a UI, like a flutter application, you don’t want your application to just wait unresponsive for the result of that function. Note that if you wait for that method to return your UI will be UNRESPONSIVE.

Now to work around that, we want to call a function, but we don’t the response right away, we want to say something like:

Hey, please go get this json file. I will ask for the result in future.

And that is a future!

Examples

Let’s get real with some examples. Lets say we want to download and deserialize a json file to some object. To do this, we need to use a Http client.

Let’s look at the one comes in with the language itself dart:io. The class is called HttpClient and the method we are interested in is get method

As you can see, this method returns a Future type of request. The actual process is not really relevant here, but the point is you will get a future by using this api. The usage will look like this

import 'dart:convert';
import 'dart:io';

main() async{
  var client = HttpClient();
  try {
    HttpClientRequest request = await client.get('gist.githubusercontent.com', 80, '/arashbi/2ef379b4de94b549f0b52f1843d0df16/raw/43912ef39649f11eb0c163badfb02b9f9a168545/sample.json');
    HttpClientResponse response = await request.close();
    final stringData = await response.transform(utf8.decoder).join();
    print(stringData);
  } finally {
    client.close();
  }
}

What can you do with a future

So what can we do with a future? This is not exacltly what we want when we call a method.

THEN

There are in fact multiple paradigms for writing code with future. The most primitive one - and admittedly the most cumbersome one - is then.

somefuture.then((value)=> print("this is the value you want"));

This method let’s you do some action when the future is indeed finished doing its job. You tell the language to do some task in background then do this thing that I gave to you.

The problem with then is that it is cumbersome to write, and read. The code ends up being too many then. Look at the probram above with then

  Future<HttpClientRequest> request =  client.get('gist.githubusercontent'
        '.com', 80, '/arashbi/2ef379b4de94b549f0b52f1843d0df16/raw/43912ef39649f11eb0c163badfb02b9f9a168545/sample.json');
    request.then((value) => value.close())
    .then((value) => value.transform(utf8.decoder).join())
    .then((value) => print(value));

Async/Await

The next approach is to use async/await keywords in the language. These keywords make the future somehow disappear from program. For example, if a function called myFunc returns a Future<String> if you call it with await you can pretend it returns String

Future<String> f = myFync();
// is equivalant to
String s = await myFunc()

So, what is the catch you might ask? The catch is that the function that has this piece of code in it, should be marked async

Future<String> someFun() async {
    String s = await myFunc();
    return s;
}

Note that there is no mention of future in the body of this function. And the type of s which we return seems to be a String, but the function signature says it returns a Future<String>!

This is because, under the hood, we are still working with Futures and someFunc will in fact return a future immediately. Why ? It has to, that is the model we are discussed, and it is still applicable here. await and async just make this system easier to read and write.