Your Second Flutter App

Nov 30 2021 Dart 2.13, Flutter 2.2.3, Visual Studio Code

Part 1: Parse Network Data

3. Understand Futures

Episode complete

Play next episode

Next
Save for later
About this episode
See versions
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 2. Create the Project Next episode: 4. Use a Model & Repository

This video Understand Futures was last updated on Nov 30 2021

A key aspect of app development is asynchronous programming. You want to keep your app user interface responsive, and asynchronous programming allows you to do that. There are a number of tasks your app will need to do that task a nontrivial amount of time, like making calls to the network or writing a file to permanent storage

You need your app to continue running while those long running tasks happen, and how long they might take to finish is unknown when you start them. When they do finish, you need your app to process any results from the long running task and then continue on.

Using such tasks is called asynchronous since the code does not run in the synchronous manner that most code runs, one line at a time in order. You’ll also hear the term concurrency used when describing such long running tasks, since they run concurrently with the rest of your app code.

The Dart data type Future, sometimes called Promise in other languages, is used when making such asynchronous calls. Futures let you run some asynchronous code and await its completion at some point in the future, at which point a value is returned.

Futures make use of what is called the Dart event loop. Dart code runs single-thread. The thread runs events from what is called the Event Queue. If you are coming from a language like JavaScript, you should be quite familiar with this approach. Things like user interactions with your app are an example of events.

The completion of a Future is another type of event that is handled by the event queue. When the Future completes, it’s return value is picked up in the event queue, and the rest of the code then continues running.

There are three possible states for Futures: Incomplete, complete with success, complete with error. The example shown here uses the getInstance method on a type called SharedPreferences. The getInstance method returns a Future of SharedPreference, meaning it runs asynchronously and returns a SharedPreference at some point in the future.

You use the then method on the Future type to determine what to do when the Future returns. catchError will be called if there is an error during the processing, and whenComplete is run whether or not there is an error, kind of like the finally block sometimes used with try/catch statements. Note that each of these methods returns the same Future instance, so they can be changed together like shown here.

There is an alternative syntax that you can use with Futures, and it utilizes the async and await Dart keywords. Those keywords are also used in other languages like JavaScript, Python and the latest version of Swift. The async/await syntax lets you write your code in a manner that looks a little more like synchronous code.

Part of the SharedPreference example from the last slide is replicated here using the async/await syntax.

You label a method as async, to indicate that it contains a long running task.

Then you use await to signify that you want to wait for the result of a Future before continuing. With your new understanding of Futures, you can continue on building the RWCourses app in the next episode.