preface

Yesterday, I posted an article “Dart development server, am I having a fever?”, thanks to the small editor, it was on the home page.

Today, I’m going to write about using the Dart language for asynchronous operations. Speaking of asynchronous operation, NodeJS students know a smile, this is our skill ah. If you play PHP or JAVA, you just look at it.

Before we demonstrate the code, let’s assume a scenario. Let’s say I have some beautiful sisters and I want to send them an email expressing my love. Here’s what the code needs to do:

  1. Receiving a request
  2. Save my email content to the database
  3. You also need to send the email to their email address.
  4. Returns the result

In this process, I was concerned about how long it would take to send an email, because I have too many sisters, and if ONE email takes too long, I can’t take care of anyone else. Which of the four steps will take longer?

Obviously, 1 and 4 take absolutely no time, 2 takes a little time, but a very short time, and 3 takes the longest time, because there are so many uncontrollable factors involved in network transmission.

What does the synchronization code look like

Let’s first simulate the above process by synchronizing the code.

Assuming that it takes 1 second to save information to the database and 5 seconds to send mail to the recipient’s mailbox, the total should be more than 6.

import 'dart:io';

main() {
  acceptRequest(); // Accept the request
  saveToDb();      // Save to the database, not too time consuming, assuming 1 second
  sendLetter();    // Sending an email to the recipient's mailbox is very time-consuming. Let's say it takes 5 seconds
  returnRes();     // Return the result
}

void acceptRequest() {
  print(DateTime.now().toString() + 'Accept request');
}

void saveToDb() {
  sleep(Duration(seconds: 1));
  print(DateTime.now().toString() + 'Database saved successfully');
}

void sendLetter() {
  sleep(Duration(seconds: 5));
  print(DateTime.now().toString() + 'Email sent successfully');
}

void returnRes() {
  print(DateTime.now().toString() + 'Return result');
}
Copy the code

Execute it and get the printed result

2021-06-29 16:40:44.993785 Accept request 2021-06-29 16:40:46.000240 Save database successfully 2021-06-29 16:40:51.002400 Send mail successfully 2021-06-29 16:40:51.002400 Returns the resultCopy the code

A quick calculation shows that the total time between receiving the request and returning the result is about 6 seconds, as expected.

What does asynchronous code look like

Just said, I have a lot of beautiful sisters, so an email takes so long, so many sisters how long ah, can you hurry up?

Sure, the code is as follows:

main() async {
  acceptRequest(); // Accept the request
  await saveToDb(); // Save to the database, not too time-consuming, take 1 second
  sendLetter(); // Send an email to the recipient's mailbox. It takes 5 seconds
  returnRes(); // Return the result
}

void acceptRequest() {
  print(DateTime.now().toString() + 'Accept request');
}

void saveToDb() async {
  await Future.delayed(Duration(seconds: 1));
  print(DateTime.now().toString() + 'Database saved successfully');
}

void sendLetter() async {
  await Future.delayed(Duration(seconds: 5));
  print(DateTime.now().toString() + 'Email sent successfully');
}

void returnRes() {
  print(DateTime.now().toString() + 'Return result');
}
Copy the code

Execute it and get a print

2021-06-29 16:47:46.931323 Accept request 2021-06-29 16:47:47.956545 Save database successfully 2021-06-29 16:47:47.959539 Return result 2021-06-29 16:47:52.960542 The email is sent successfullyCopy the code

This result, but need to watch. There are two points that need special attention:

  1. Between receiving the request and returning the result, it took about a second
  2. Send email success, unexpectedly appear after the return result, interval 5 seconds

Why is that? In fact, that’s the beauty of the Dart language for asynchronous operations.

Dart executes tasks in code order by default.

However, when the sendLetter is executed, it is found that it is an async asynchronous operation, and there is no need to wait for it, then it is skipped directly and the returnRes are executed, so the return result is printed

Once the result is returned, the browser request, if it was a browser request, ends directly. But that wasn’t the end of the story. Dart continued with the sendLetter that had just been skipped, so it finally printed out that the message was sent successfully

Overall, IT took me one second to send the email, compared to six seconds before, a 500% increase in efficiency

Yeah, yeah, it’s great. I can take care of more sisters.

Await async is what

Those of you who are eagle-eyed probably see it, in the code above

main() async {
  acceptRequest(); // Accept the request
  await saveToDb(); // Save to the database, not too time-consuming, take 1 second
  sendLetter(); // Send an email to the recipient's mailbox. It takes 5 seconds
  returnRes(); // Return the result
}
Copy the code

SaveToDb saves the database and sendLetter sends the oil price is time-consuming operation, why is saveToDb added with await?

This is because saveToDb is also an asynchronous operation. If we do not add await, it will be skipped like sendLetter to send mail and executed after the browser returns the result. This creates a problem. If writing to the database fails, but you’ve already told the user that it succeeded, isn’t that embarrassing?

So saveToDb precedes with await, telling Dart that even though this code is asynchronous, you want to execute it synchronously.

conclusion

When an operation is very time-consuming, we can set it to async and return the information to the user and process it later.

If I want to make an asynchronous operation synchronous, I can add the keyword await to indicate that I am willing to wait for the asynchronous result.

Dart provides mechanisms for asynchronous operations, so you can use them easily.

NodeJS players are crying because their skills have been stolen.