The concept of Future data type is very easy to understand. Although the official documentation has explained this concept very well, in this article I will try to explain it in my own words, which will hopefully help you get your head around it, if you have not already.
When a function returns a
Future, it means that it takes a while for its result to be ready, and the result will be available in the future.
The most famous example of a function that may take some time to return the result is
http.get(url) which is usually used to call RESTFul API, where we have to send an HTTP request and wait for the response. In the following example,
http.get() method returns a
Calling a function that returns a Future, will not block your code, that’s why that function is called asynchronous. Instead, it will immediately return a Future object, which is at first uncompleted.
Future<T> means that the result of the asynchronous operation will be of type
T. For example, if a function returns
Future<String>, this means that in the future, it will provide a string to you.
For the sake of practicing, we can use one of the Future constructors to create our own Future object. The following code creates an instance of
Future<String> which will complete immediately. Note how we have provided an anonymous function as the parameter of the Future’s constructor. The return value of this anonymous function determines the type of the instantiated future object. Here “Latest News” is of type
String, therefore an instance of
Future<String>will be created.
To simulate a Future that completes after some time, we can use the
Future.delayed constructor. The
future object in the following example will complete after two seconds:
The result of the Future is available only when the Future is completed.
You can access the result of the Future using either of the following keywords:
Suppose that the
getNews function returns an instance of
You can consume the result of this function in either of the following ways:
Note that the
await keyword can only be used in the body of an
The result of an
async function must be a
Tip: If a function returns a
Future, it’s considered asyncrounous; you do not need to mark the body of this function with
asynckeyword is necessary only if you have used the
awaitkeyword in the body of your function.
If your asynchronous function does not return anything (for example if it only prints something), the return type of function should be
then keyword returns a
Future<T> as well, it means that you can chain them:
The type of
Future<T> returned by
then keyword is determined by the return value of the function defined in the body of
then()returns a new
Futurethat will complete with the value returned by
The following code is a real-world example. In this piece of code, I have used the permission_handler package to check if the application has permission to access the phone contacts. The
checkPermissionStatus function returns a future object.
Checking permissions with
checking permissions using
The purpose of this article was to summarize the well written official documentation: https://www.dartlang.org/tutorials/language/futures
I would suggest you watch the following tutorial as well:
I tried to keep this article as concise as possible. One thing I didn’t talk about is how to handle errors while working with Future objects. If you are using the Future API (“then” keyword), you will be able to catch errors using
catchError() function, otherwise if you are using the “await” keyword, simply use try-catch blocks to handle the errors.
Thanks for reading :)