Analysis of the principle of async and await asynchronous programming in Flutter

Analysis of the principle of async and await asynchronous programming in Flutter

Inscription
-Holding the sword in the world, starting from your accumulation of bits and pieces, you must strive for perfection wherever you go, that is, toss every day.

** You may need
CSDN NetEase Cloud Classroom Tutorial
Nuggets EDU Academy Tutorial
Know almost Flutter series articles

After writing a few articles about the use of asynchronous programming, it is time to share with you the principles of Flutter asynchronous programming.

Header1 Header2
Flutter delayed tasks, Flutter implements delayed tasks through Future and Timer Basic use of async and await in Flutter asynchronous programming
Basic use of async and await in Flutter asynchronous programming Flutter asynchronously loads FutureBuilder redrawing solution

1Basic concepts of asynchronous programming

1.1 Task scheduling

Let’s talk about task scheduling first. The task scheduling of most operating systems (such as Windows and Linux) is a preemptive scheduling method that uses time slice rotation. For a single-core CPU, two tasks are executed in parallel, but the CPU is actually doing it. Fast switching, the user does not feel the switching pause, just like the 220V AC light display principle, that is to say, a task is executed for a short period of time and then forced to pause to execute the next task, and each task is executed in turn.
A short period of time during the execution of a task is called a time slice. The state when the task is being executed is called the running state. After the task is executed for a period of time, it is forced to suspend to execute the next task. The suspended task is in the ready state and waits for the next time slice belonging to it. When it arrives, the stop and execution switching of tasks is called task scheduling.

1.2 Process

The core of the computer is the CPU, which undertakes all computing tasks, and the operating system is the manager of the computer. It is responsible for task scheduling, resource allocation and management. There are multiple processes running in the operating system, and each process is a A dynamic execution process of a certain independent function program on a data set is the carrier of the application program.
The operating system will allocate system resources (CPU time slices, memory and other resources) based on the process as the unit. The process is the smallest unit of resource allocation, that is, the smallest unit of the operating system.

1.3 Thread

Thread is a concept in process, and a process can contain multiple threads.
Task scheduling uses the preemptive scheduling method of time slice rotation, and the process is the smallest unit of task scheduling.
By default, there is generally only one thread in a process, and the process itself is a thread, so a thread can be called a lightweight process.

1.4 Coroutines

A coroutine is a thread-based but more lightweight existence than a thread. It is a concept in a thread. A thread can have multiple coroutines.

In the traditional J2EE system, each request occupies a thread to complete the complete business logic (including transactions). So the throughput of the system depends on the time-consuming operation of each thread. If you encounter time-consuming I/O behavior, the throughput of the entire system will drop immediately, because the thread has been blocked at this time. If there are many threads, there will be many other threads waiting and idle (waiting for the previous The thread can only be executed after execution), resulting in incomplete resource application.

The most common example is synchronous blocking JDBC. During the connection process, the thread does not use the CPU to do calculations at all, but is in a waiting state. In addition, too many threads will also bring more ContextSwitch (context switch) overhead .

The emergence of coroutines, when there is a long-term I/O operation, by giving up the currently occupied task channel, executing the next task, by implementing scheduling in the thread, eliminating the overhead on ContextSwitch and avoiding getting into the kernel The performance loss caused by the level of context switching has broken the performance bottleneck of threads on IO. From a programming perspective, the idea of ​​a coroutine is essentially the active yield and resume mechanism of control flow.

2 The principle of asynchronous programming in the Flutter project

For example, an APP developed by Flutter is installed on a mobile phone. When the APP icon is clicked to start, the mobile operating system will create a process for the current APP, and then start the project built by Flutter in the Flutter project through the main function.

Dart is a language based on the single-threaded model, so our general asynchronous operations in Flutter are actually implemented through single-threaded scheduling tasks.

The thread mechanism in Dart is called isolate. In the Flutter project, the running Flutter program consists of one or more isolates. The Flutter project started by default is started by the main function to create a main isolate. The follow-up will There is a special article to discuss the development and use of isolate, where our main isolate is the main thread of Flutter, or the UI thread.

2.1 Dart event loop

The single-threaded model mainly maintains an event loop (Event Loop) and two queues (event queue and microtask queue)

When the Flutter project program triggers such as click events, IO events, and network events, they will be added to the eventLoop. The eventLoop is always in the loop. When the main thread finds that the event queue is not empty, it will take out the event and execute it. .

The microtask queue only processes tasks in the current isolate, and has a higher priority than the event queue. Just like a VIP waiting room in an airport, VIP users always board the plane first before opening the public queue entrance. If in the event queue Insert microtask. When the current event is executed, the microtask event can be inserted in the queue. The existence of the microtask queue provides Dart with a solution to the task queue.

When the event loop is processing microtask events, the event queue will be blocked. At this time, the app cannot draw the UI and respond to events such as mouse events and I/O.

The task switching in these two task queues is equivalent to the coroutine scheduling mechanism.

2.2 Overview of Future

Future is an event. Every handle marked by await is also an event. The task created by the timer is also an event. Every time a Future is created, it will be thrown into the event queue.

Using the combination of async and await, you can insert events into the event queue to implement asynchronous operations.

The main function of Future is to provide a chain call method and a complete set of methods for processing asynchronous tasks.

2.3 Overview of Future's Common Methods

Flutter provides the following three methods, let us register callbacks to monitor the results of processing Future asynchronous information:

//处理完成时候的回调,一般都是成功回调
Future<R> then<R>(FutureOr<R> onValue(T value), {Function onError});
//处理失败的回调,比如throw一个error就会走到这里
Future<T> catchError(Function onError, {bool test(Object error)});
//Future.whenComplete总是在Future完成后调用,不管Future的结果是正确的还是错误的。
Future<T> whenComplete(FutureOr action());

Future's construction method to create a basic Future

var f1 = Future(() {
  print("1111");
});
print("33233");

//33233
//1111

Create a Future with a specified return value

Future.value("Success").then((value) => (print('测试$value')));

Create a Future with delayed execution

//延迟三秒执行
 Future.delayed(Duration(seconds: 3), () {
   print("future delayed");
 });


According to a certain set, create a series of Futures, and execute these Futures in order

Future.forEach([1,2,3], (item) {
    return Future.delayed(Duration(seconds: 2),() {
      print(item);
    });
});

//1
//2
//3

Perform multiple asynchronous tasks serially

var f1 = Future.delayed(Duration(seconds: 1),() => (1));
var f2 = Future.delayed(Duration(seconds: 2),() => (2));
var f3 = Future.delayed(Duration(seconds: 3),() => (3));
Future.wait([f1,f2,f3]).then((value) => print(value)).catchError(print);

The asynchronous tasks created above are all tasks added to the event queue, creating a future that runs in the microtask queue. The priority of the microtask queue is higher than the event queue.

Future(() => (print(11111)));
Future(() => (print(22222)));
Future.microtask(() => (print(33333)));

Public account my big front-end career

Guess you like

Origin blog.csdn.net/zl18603543572/article/details/107943904