Skip to main content

Dart Programming - Async

 

Dart Programming - Async



Asynchronous Programming Dart Asynchronous Programming in Dart 



Flutter is getting more popular than ever! But before you start learning the framework, you need to learn the programming language first. I know that's annoying and it seems like a waste of time. But, that's the challenge that every developer must face.

Dart is a powerful programming language by Google that aims to help developers to build web applications for both client and server, and now mobile apps with Flutter. Just like JavaScript, Dart is an asynchronous programming language. It means that you can run a piece of code without blocking any other tasks, even though, it runs in a single thread.

Dart also use something called an event loop to make the asynchronous code works. Actually, you don't need to really care about this because the Dart VM is doing everything for you, but at least you guys understand how it works and why does it exist.

Future

One of the basic implementation of asynchronous coding pattern in Dart is Future. If you already familiar with JavaScript, Future have the exact same concept with Promise. Basically, you have a piece of code that you want to run whenever some event is triggered.

Once your function gets a Future, you need to decide what do you want to do when the Future is not completed yet, what do you want to do when it's completed, and what do you want to do when it's completed with an error.

How Future Works.

Take a look at this code below.

void fetchPost() {
  http.get('https://jsonplaceholder.typicode.com/posts/1')
    .then((response) {
      print(response);
    });
}

In this example, we have a function that use the http library make an http request from an API. The http.get method returns a Future. So, we use then to register a callback that will be triggered when the request is completed.

When you run this function, the event loop catch it, and system started to make a request to the server. While waiting for the response from the API, the event loop still doing its job. Maybe some other events come in, or user do some stuff, your Future still waiting for either a data or an error.

When the data arrives, the callback that we register with then method gets triggered. Now, your piece of code get executed and print the response to the console.

Handling Errors

Now we know that we can use the then method to tell the Future what we want to do when the data arrives successfully. But, how about if the there is something wrong in our request like; connection is interrupted, or the form data is not valid?

Well, we can use the catchError method to tell Dart what we want to do when the Future is throwing an error.

void fetchPost() {
  http.get('https://jsonplaceholder.typicode.com/posts/1')
    .then((response) {
      print(response);
    })
    .catchError((error) {
      print("Something went wrong: ${error.message}");
    });
}

catchError callback gets an error as the first parameter. So, you know what's exactly went wrong.

So far so good! Now I'm going to show you how to make your own instance of the Future.

Create Our Own Future

Most of the time, you don't need to create your own Future. That's because many third-party libraries already generates a Future for you. For instance, network library, accessing device camera, and many other. But still, you can build your own Future by using the Future constructor.

Let me show you what I'm talking about.

import 'dart:async';

void main() {
  final myFuture = Future(() {
    print("Hello from the future!");
    return true;
  });

  print("Done!");
}

If you run this code, you will see that the "Done!" string is printed first. Why? because the code inside our Future runs asynchronously. If you already have the value of the Future, you can just use the Future.value method to return a Future with the given value like the example below. Sometimes it's very helpful for testing.

final myFuture = Future.value("Hello from the future!");

Or, if you want to return an error, you can just use the Future.error method.

final myFuture = Future.error(Exception());

Async & Await

Most programming languages have async and await in their syntax. Basically, their are just an alternate syntax to handle asynchronous code like Future and Streams to make it looks cleaner and readable. Let me gives you an example.

void fetchPost() {
  http.get('https://jsonplaceholder.typicode.com/posts/1')
    .then((response) {
      print(response);
    })
}

Remember this piece of code right? Well, this function looks OK. But actually, this code will look a lot messier if we want to use more than one asynchronous function.

First of all, we need to add async keyword to the function you want to use await. If you don't, the Dart compiler will give you a syntax error.

void fetchPost() async {  // ...
}

Then, add the await keyword to the asynchronous function that returns a Future and store the result value inside a variable like below.

void fetchPost() async {
  final result = await http.get('https://jsonplaceholder.typicode.com/posts/1');}

Finally, you can directly print the result value to the console right after the request function.

void fetchPost() async {
  final result = await http.get('https://jsonplaceholder.typicode.com/posts/1');
  print(result);}

The only thing to keep in mind is you only can use await keyword inside async function. That's it!

The big difference by using async & await and not using it is when we want to handle more than one Future at the same time

Using async & await:

import 'dart:convert';
import 'package:http/http.dart';

void fetchUserPosts(token) async {
  // Fetch user data
  final userResponse = await http.get('https://yourapi.com/user?token=$token');
  final user = json.decode(userResponse.body);

  // Fetch posts data
  final postsResponse = await http.get("https://yourapi.com/posts?userId=${user['id']}");
  final userPosts = json.decode(postsResponse.body);

  print(userPosts);
}

Using then & catch:

import 'dart:convert';
import 'package:http/http.dart';

void fetchUserPosts(token) {
  http.get('https://yourapi.com/user?token=$token')
    .then((userResponse) {
      final user = json.decode(userResponse.body);

      http.get("https://yourapi.com/posts?userId=${user['id']}")
        .then((postsResponse) {
          final userPosts = json.decode(postsResponse.body);
          print(userPosts);
        });
    });
}


Doucmentation





10
Asynchronous Programming

You’ve come a long way in your study of the Dart programming language. This chapter is an important one, as it fills in the remaining gaps needed to complete your apprenticeship. In it, you’ll not only learn how to deal with code that takes a long time to complete, but along the way, you’ll also see how to handle errors, connect to a remote server and read data from a file.

Your computer does a lot of work, and it does the work so fast that you don’t usually realize how much it’s actually doing. Every now and then, though, especially on an older computer or phone, you may notice an app slow down or even freeze. This may express itself as jank during an animation: that annoying stutter that happens when the device is doing so much work that some animation frames get dropped.

Tasks that take a long time generally fall into two categories: I/O tasks, and computationally intensive tasks. I/O, or input-output, includes things like reading and writing files, accessing a database, or downloading content from the internet. These all happen outside the CPU, so the CPU has to wait for them to complete. Computationally intensive tasks, on the other hand, happen inside the CPU. These tasks may include things like decrypting data, performing a mathematical calculation, or parsing JSON.

As a developer, you have to think about how your app, and in particular your UI, will respond when it meets these time-consuming tasks. Can you imagine if a user clicked a download button in your app, and the app simply froze until the 20 MB download was complete? You’d be collecting one-star reviews in a hurry.

Thankfully, Dart has a powerful solution baked into the very core of the language that allows you to gracefully handle delays without blocking the responsiveness of your app.

Concurrency in Dart

thread is a sequence of commands that a computer executes. Some programming languages support multithreading, which is running multiple threads at the same time, while others do not. Dart, in particular, is a single-threaded language.

“What? Was it designed back in 1990 or something?”

No, Dart was actually created in 2011, well into the age of multicore CPUs.

“What a waste of all those other processing cores!”

Ah, but no. This choice to be single-threaded was made very deliberately and has some great advantages as you’ll soon see.

Parallelism vs. concurrency

To understand Dart’s model for handling long-running tasks, and also to see why the creators of Dart decided to make Dart single-threaded, it’s helpful to understand the difference between parallelism and concurrency. In common English, these words mean approximately the same thing, but in computer science, there’s a distinction.



Dart isolates

Dart’s single thread runs in what it calls an isolate. Each isolate has its own allocated memory area, which ensures that no isolate can access any other isolate’s state. That means that there’s no need for a complicated locking system. It also means that sensitive data is much more secure. Such a system greatly reduces the cognitive load on a programmer.

But isn’t concurrency slow?

If you’re running all of a program’s tasks on a single thread, it seems like it would be really slow. However, it turns out that that’s not usually the case. In the following image, you can see tasks running on two threads in the top portion, and the same tasks running on a single thread in the bottom portion.




Comments

All Post

When to Use Waterfall vs. Agile

  We compare the benefits and drawbacks of using two well-known software development methodologies, Waterfall and Agile, and lay out when it might be more suitable to use one over the other – or combine practices of both – for your product initiative. When developing a new software product, your team will need to navigate which development methodology is right for your initiative. In the world of managing  software development  projects, the topic of Agile vs Waterfall is widely debated. Many thought leaders and Agile enthusiasts in the industry have argued Waterfall is dead, however, traditional organizational environments and processes have led to it still being widely used today. A 2017 report from the Project Management Institute shows that  51% of the organizations surveyed use Waterfall either often or always . The reality is, each software development project poses its own unique challenges and requirements. It’s not a matter of deciding which development meth...

Flutter form validation: Full guide for you to make Flutter form

  Flutter form validation Getting started with form validation in Flutter The Flutter SDK provides us with an out-of-the-box widget and functionalities to make our lives easier when using form validation. In this article, we’ll cover two approaches to form validation: the form widget and the Provider package. You can find more information on these two approaches in the official Flutter docs. Creating a form in Flutter First, we are going to create a simple login page that has the following fields: Email Name Phone number Password For the validation, we want the users of our app to fill in the correct details in each of these fields. The logic will be defined as such: First, for the name field, we want the user to enter a valid first name and last name, which can be accompanied by initials. For the email field, we want a valid email that contains some characters before the “@” sign, as well as the email domain at the end of the email. For phone number validation, the user is expecte...

How to change the language on Android at runtime and don’t go mad

  How to change the language on Android at runtime and don’t go mad TL;DR There is a library called Lingver that implements the presented approach with just a few lined of code.  Check it out! Introduction The topic is old as the hills, but still is being actively discussed among developers due to frequent API and behavior changes. The goal of this post is to gather all tips and address all pitfalls while implementing this functionality. Disclaimer Changing the language on Android at runtime was never officially encouraged or documented. The resource framework automatically selects the resources that best match the device. Such behavior is enough for common applications, so just make sure you have strict reasons to change it before proceeding further. There are a ton of articles and answers on Stack Overflow but they usually lack enough of explanation. As a result, when this functionality gets broken, developers can’t easily fix it due to the messy API and lots of deprecated t...

7 Key Android Concepts

  Although the Android platform is open and customizable, Android users have become accustomed to constructs developed by Google for Android devices. Although the Android platform is open and customizable, Android users have become accustomed to constructs developed by Google for Android devices. Moreover, the use of these Android concepts is vital in developing an application quickly – custom Android designs can take up to 10 times longer! Android UI Controls Android provides a number of standard UI controls that  enable a rich user experience . Designers and developers should thoroughly understand all of these controls for the following reasons: They are faster to implement. It can take up to ten times longer to develop a custom control than to implement a user interface with standard Android controls. They ensure good performance. Custom controls rarely function as expected in their first implementation. By implementing standard controls, you can eliminate the need to test,...

Clean Code and the Art of Exception Handling

  Clean Code and the Art of Exception Handling Exceptions are as old as programming itself. An unhandled exception may cause unexpected behavior, and results can be spectacular. Over time, these errors have contributed to the impression that exceptions are bad. But exceptions are a fundamental element of modern programming. Rather than fearing exceptions, we should embrace them and learn how to benefit from them. In this article, we will discuss how to manage exceptions elegantly, and use them to write clean code that is more maintainable. Exceptions are as old as programming itself. Back in the days when programming was done in hardware, or via low-level programming languages, exceptions were used to alter the flow of the program, and to avoid hardware failures. Today, Wikipedia  defines exceptions as: anomalous or exceptional conditions requiring special processing – often changing the normal flow of program execution specialized programming language constructs or computer h...

How to them the background of the Android options menu items

  “What we’ve got here is… failure to theme. Some views you just can’t reach. So you get what we had here last project, which is the way Android wants it… well, it gets it. I don’t like it any more than you men.” – Captain, Road Prison 36 Some of you might recognize the previous paragraph as the introduction of Guns ‘N Roses’ Civil War or from the movie Cold Hand Luke starring Paul Newman. This is the feeling I get when I try to create a custom theme for an application on Android. The Android SDK does permit some level of theming, which is not really well documented to start with. Other things are hard-coded, “so you get what we had here last project”. Now, one of the things your application will most likely use is the Options menu, which is the menu you see when you press the hard menu key. It is kind of… orange. In our last project, we had to completely remove the orange in favor of our customer’s color scheme, which is on the blue side. I couldn’t find a way to change the menu i...

Android Jetpack Compose

  Jetpack Compose Tutorial for Android: Getting Started Jetpack Compose is Android’s modern toolkit for building native UI. It simplifies and accelerates UI development on Android. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs. At Google I/O 2019, Google first announced  Jetpack Compose . Jetpack Compose is Google’s response to the declarative UI framework trend, which the Android team is developing to fundamentally change the way developers create UI, making it easier and faster to write, and more performant to run. It is a part of the Jetpack suite of libraries and as such should provide compatibility throughout platform versions, removing the need to avoid certain features, because you’re targeting lower-end devices or older versions of Android. Although it’s still in an alpha , Compose is already making big waves in the Android community. If you want to stay up-to-date on the latest and greatest technology, read on! In this tutor...

Loops in Dart 💪💪💪😎😎😎

       Loops in Dart   💪💪💪😎😎😎 Dart Loops In Programming, loops are used to repeat a block of code until certain conditions are not completed. For, e.g., if you want to print your name 100 times, then rather than typing print(“your name”); 100 times, you can use a loop. There are different types of loop in Dart. They are: For Loop For Each Loop While Loop Do While Loop Info Note : The primary purpose of all loops is to repeat a block of code. Print Your Name 10 Times Without Using Loop Let’s first print the name 10 times without using a loop. void main() { print( "John Doe" ); print( "John Doe" ); print( "John Doe" ); print( "John Doe" ); print( "John Doe" ); print( "John Doe" ); print( "John Doe" ); print( "John Doe" ); print( "John Doe" ); print( "John Doe" ); } Show Output ...

MVVM architecture, ViewModel and LiveData (Part 1)

  MVVM architecture, ViewModel and LiveData (Part 1) During Google I/O, Google introduced  architecture components  which includes  LiveData  and  ViewModel  which facilitates developing Android app using MVVM pattern. This article discusses how can these components serve an android app that follows MVVM. Quick Definition of MVVM If you are familiar with MVVM, you can skip this section completely. MVVM is one of the architectural patterns which enhances separation of concerns, it allows separating the user interface logic from the business (or the back-end) logic. Its target (with other MVC patterns goal) is to achieve the following principle  “Keeping UI code simple and free of app logic in order to make it easier to manage” . MVVM has mainly the following layers: Model Model represents the data and business logic of the app. One of the recommended implementation strategies of this layer, is to expose its data through observables to be decoupled ...