21Aug 2020

Asynchronous Programming With Dart

Hi there!

In the past, we’ve had to deal with a whole bunch of programming concepts. I just wish to announce that this is yet another concept you should understand, because understanding asynchronous programming is as important for growing and becoming a better developer –  (let’s just say it makes you know an extra techy term).

In a quest to be able to code fast, saving processing time for both developers and users, asynchronous programming became a way out to manage a single process aside from the main program flow.

This article is for newbies, wannabees, developers, and anyone that wishes to understand the concept of asynchronous programming in Dart.

I would like to answer the “WHAT, WHY, and HOW” questions. I will also be sharing an analogy and give an example that would help you understand asynchronous programming in Dart.

To get the most out of this article, you should have the following:

  • A curious mind, as always.
  • A basic knowledge of the dart programming language.
  • An understanding of programming and some programming concepts(for newbies).

What Is Asynchronous Programming?

what-is-asychronous-programming

Asynchronous programming could be defined as a concept of programming that allows a part of a program run separately from the main program. The concept of asynchronous programming is as important because it saves time and improves application performance.

When we are writing code, there are lines of code that take a very short amount of time to execute. For example, if we wish to run a single print statement like:

Alt-text: A simple print statement.

This is a single-line statement that prints “Hello Flutteristas!” when we hit on the run button and this takes fractions of a second to complete. But you know, if all our programs were as simple, we probably wouldn’t need computers nor a need to write programs, we can all agree that our brains could do better.

Unfortunately, we don’t always have a need to simply run single line print statements. Not when we have to send astronauts into space or build cryptocurrency wallets or banking systems or all the amazing things we do with programming.

So, sometimes there are things that take more processing time.

Now, those hard tasks are the reason why we not only need to adopt coding practices, but we need to find a way to save time while we could.

On the other hand, synchronous programming is a concept that allows a program to run sequentially without skipping any steps or waiting on a task to complete before it moves to the next task. In synchronous programming, the process moves from top to bottom.

The above image shows the differences between synchronous and asynchronous processes.

Why Asynchronous Programming?

why-asynchronous-programming

Asynchronous programming allows your program to complete a task while waiting for another operation to complete its process.

Given the above definitions, you could be wondering why you would need to choose asynchronous programming over synchronous programming?

Well, aside from the fact that asynchronous programming saves application load time and improves performance, it also helps in cases where we need:

How And Where To Use Asynchronous Programming?

In recent times, we’ve seen more developers use asynchronous programming in even the smallest cases. It is important to understand that simple calculations shouldn’t be implemented using asynchronous programming, as it burns the user’s device memory and CPU.

However, to implement asynchronous programming, it is important to use it when the app needs to pre-load data before the app loads.

For example, While a splash screen loads, it’s important to load the onboarding screens, especially if the images on the onboarding screens are loading from the internet, so while the initial splash screen fades, the onboarding loads up just fine.

Real-Life Cooking Analogy

To better explain asynchronous programming, I will like to share an analogy.

Let’s say I am having some friends over for some pair programming exercises over the weekend and since I am a kind and homely person, I decide to prepare Nigerian Jollof, coffee, fresh juice, and even place an order for some cocktail drinks to be delivered to us.

Here goes my checklist for the evening:-

  1. Make some Nigerian Jollof.
  2. Slice up some fresh fruits and make fresh juice.
  3. Pour in fresh coffee beans and brew.

In order for me to be able to pull this off, I may decide to start with making my tasty pot of jollof rice. Say, I already did all my magic and put the rice to get done. I could choose to stand there and wait for it to get done, then bring it down before I start to cut up fresh fruits.

But what if I decide to start chopping my fruits while the rice is still cooking? And even after that, if I still have time, I can always put on the coffee brewer to get the coffee ready. That saves me some extra time I would’ve wasted on waiting for the rice to get done.

It’s simple, asynchronous programming saves us some time and hastens processes.

Implementation In Dart

Asynchronous programming in Dart is characterized by the Future and Stream classes.

Furthermore, when we perform asynchronous operations in Dart, we make use of the Future class, as well as the async and await keywords. Before we dive deep, let’s understand these terms.

Async and Await: The async and await keywords are the simplest ways to understand the concept of asynchronous programming. It’s just a fancy way of marking a function as async and telling the function to await any async processes before it continues.

It’s just like saying “Hey Dear function, if you happen to see the word await anywhere please pause and wait for the process to finish before you move to the next line”.

A sample async-await program:

void main() async {
print(“A”);
//   Duration is a Dart class that defines a period of time. In this case, it represents 1 ms.
await futurePrint(Duration(milliseconds: 1), “B”)
// A future, we gotta pause on await
.then((status) => print(status));
print(“C”);
await futurePrint(Duration(milliseconds: 2), “D”)
.then((status) => print(status));
print(“E”); }
Future<String> futurePrint(Duration dur, String msg) {
return Future.delayed(dur).then((onValue) => msg);
}

You do need to understand that this code can also be written as:

void main() 
{ print(“A”); 
print(“B”); 
print(“C”); 
print(“D”); 
print(“E”); 
}

But this is the simplest case scenario, we already knew what the outcome of the program would be. What if we have no clue as to what the results of the async functions would be?

In a real-life case scenario, we are either waiting to download an image from NASA or loading information from an HTTP request.

A future is the foundational class of all async programming in Dart. A future is an instance of the Future class.

In plain English, I’ll like to explain the future as a promise. You know when you step into a coffee store, you approach the waiter, place an order for a cup of coffee. The waiter gives you a receipt as a promise to get you a cup in a few minutes/seconds.

This receipt just guarantees that sometime in the future the waiter will fulfill his/her promise by delivering a cup of coffee when it’s ready.

All you need to do is simply wait for the waiter to call you and hand you a cup of coffee. The receipt is a future guarantee that a value will be returned but it’s not quite ready yet.

However, to call a future you can always say:

myFutureMethod().then((returnValue) => … do some code … );

A future can be in three states. For example, I’ll describe the future as a gift box. Say it’s your birthday, and friends are coming over and of course, there will be gifts.

A friend mails you a gift box, but it’s closed. You’re excited and can’t wait to open the box. You step aside for a second, and take a peek at the box – pops it open and voila! There’s value or not or at worst you were mailed the wrong box.

A future can be in three states:

  • Firstly, it is in an uncompleted state– that’s when the box ain’t open. 
  • Then it moves to a state where it is either completed with data or
  • Completed with an error.
3-states-of-futures-in-dart

Error Handling

In programming, the chances of occurrence of an error super high. When we are expecting a certain piece of data from our async functions and somehow there was a network breach or if the data was not available at the time, we use error-handling techniques to gracefully handle errors.

In Dart, onError and try/catch are both used to handle errors.

The first way to catch errors is to use the ‘ol future type’. There’s a method called catchError for this, and is shown below:

Future futurePrint(Duration dur, String msg) async { 
return Future.delayed(dur).then((onValue) => msg);

main() { 
futrePrint(Duration(milliseconds: 2), “D”) 
.then((status) => print(status)) 
.catchError((err) => print(err));
}

Try And Catch

Handles asynchronous errors. We wouldn’t want our users to be caught unawares by showing them a flutter red-screen-of-death. So instead, we use the try-catch block to keep the screen busy.

If our program successfully compiles (without errors), it skips the catch block and keeps the process running. The catch block is a simple safe-fail that executes when there is a glitch in the try block.

The structure looks like this:

void main() async { 
try { 
print(“A”); 
await futurePrint(Duration(milliseconds: 1), “B”) 
.then((status) => print(status)); 
print(“C”); 
await futurePrint(Duration(milliseconds: 2), “D”) 
.then((status) => print(status)).catchError((err) => print); 
print(“E”);
} catch(error) { 
print(“Arghhh!! — $error”); }
}

Streams

One of the challenges in creating beautiful UI is handling data asynchronously. Like rendering a weather page while you wait for the real data to be fetched via an HTTP request.

Streams is a specific class in Dart and just a piece of the observable pattern. Streams provide a way for classes or objects to be reactive.

In other programming languages, streams are referred to as Observables – these are asynchronous programming patterns.

Conclusion

I believe this article helped you to understand the concept of asynchronous programming and how to implement it in Dart. We’ve also learned about concepts like error-handling, streams, futures, and all. In subsequent articles, we will dive deep into each concept explained above.

I do understand that this article is a little bit too basic, but that’s the point right? Every article out there wants to explain these terms in a very technical way, but this article seeks to explain these things so even a newbie developer could grasp the concept easily.

Implementing asynchronous programming concepts could appear difficult, but good practice helps make it easier. Trust me when I say, it gets easier.

Finally, please do well to reach out with your questions, suggestions, and criticisms about this article via email or you could drop your comments in the comments section below.

Acodez is a renowned website development and web development agency in India. We offer all kinds of web design and web development services to our clients using the latest technologies. We are also a leading digital marketing company providing SEO, SMM, SEM, Inbound marketing services, etc at affordable prices. For further information, please contact us.

Looking for a good team
for your next project?

Contact us and we'll give you a preliminary free consultation
on the web & mobile strategy that'd suit your needs best.

Contact Us Now!
Jamsheer K

Jamsheer K

Jamsheer K, is the Tech Lead at Acodez. With his rich and hands-on experience in various technologies, his writing normally comes from his research and experience in mobile & web application development niche.

Get a free quote!

Brief us your requirements & let's connect

Leave a Comment

Your email address will not be published. Required fields are marked *