Dart is a single-threaded language that provides future, Stream, background WOTK, and other events and asynchronism. For Flutter, this section explains how Dart works in the background: isolation and event loops.


All of the Dart code runs the quarantine program there. It is like a small space on the machine, with its own private block of memory and a single thread running an event loop.

In many other languages, such as C ++, you can have multiple threads sharing the same memory and running whatever code you need. However, in Dart, each thread is in its own quarantine, has its own memory, and only processes events (more in a minute).

Many Dart applications run all the code in a single isolation, but you can have more than one if you need to. If the amount of computation to be performed is so large that it might result in frame loss if it runs in primary isolation, use the isolate.spawn () or compute () function of Flutter. Both of these functions create a separate isolator to process numbers, leaving your main isolator free to (for example) rebuild and render the widget tree.

The new quarantine has its own event loop and memory that is not allowed to be accessed even if the original quarantine is the parent of the new quarantine. That’s the name for isolation: these small Spaces are isolated from each other.

In fact, the only way isolators can work together is by passing messages back and forth. One quarantine sends a message to the other, and the receiving quarantine uses its event loop to process the message.

The lack of shared memory may sound strict, especially if you’re using a language like Java or C ++, but it has some key benefits for Dart coders.

For example, memory allocation and garbage collection in isolation do not require locking. There is only one thread, so if it is not busy, you know that memory has not changed. This works well for Flutter applications, which sometimes need to quickly build and dismantle a bunch of widgets.

Event loops

Now that you have a basic introduction to isolation, let’s dive into what really makes asynchronous code possible: event loops. Imagine the life cycle of an application stretching out on a timeline. The application starts, the application stops, and in between a series of events – I/O from the disk, finger taps from the user… All kinds of things. Your application cannot predict when these events will occur or in what order, so you must use a thread that never blocks to handle all of them. Therefore, the application runs an event loop. It takes the oldest event from the event queue, processes it, returns to the next event, processes it, and so on until the event queue is empty. As the application runs – you click on the screen, download content, and the timer turns off – the event loop repeats itself, processing these events one at a time.

When the operation is interrupted, the thread simply hangs out, waiting for the next event. It can trigger the garbage collector, get coffee, and so on. All of Dart’s advanced API and language features for asynchronous programming (futures, flows, asynchrony, and wait) are built on top of this simple loop. For example, suppose you have a button that starts a network request, like this:

RaisedButton( child: Text('Click me'), onPressed: () { final myFuture = http.get('https://example.com'); myFuture.then((response) { if (response.statusCode == 200) { print('Success! '); }}); },)Copy the code

When you start your APP, Flutter compiles the button, then renders it, and the APP starts waiting for events.

The event loop you apply just sits idle, waiting for the next event. Events unrelated to the button may come in and be processed while the button sits there waiting for the user to click on it. Eventually they did, and the click event entered the queue.

The event will be handled. Flutter looks at it, and the rendering system says, “Those coordinates match the raised button,” so Flutter executes onPressed. This code initiates a network request (returning a future request) and registers a future completion handler using the THEN () method. And nothing more. The loop has finished processing the click event and has discarded it. Right now, onPressed is a property of RaisedButton, and the network event callback is used for the future, but both techniques do the same basic thing. They are both a way of telling Flutter, “Hey, later, you may see a certain type of event. When you do, execute this code.” So, onPressed is waiting for a click, and the future is waiting for network data, but from Dart’s perspective, these are just events in the queue. This is how asynchronous coding works in Dart. Futures, data flow, async and wait — these apis just tell you your way through Dart’s event loop, “Here’s some code, please run it later.” If we review the code example, you can now see exactly how it breaks down into event-specific chunks. There are initial versions (1), click events (2), and network response events (3).

RaisedButton( / / (1)
  child: Text('Click me'),
  onPressed: () { / / (2)
    final myFuture = http.get('https://example.com');
    myFuture.then((response) { / / (3)
      if (response.statusCode == 200) {
        print('Success! '); }}); },)Copy the code

As you get used to using asynchronous code, you’ll start to recognize these patterns here and there. As you move on to higher-level apis, it helps to understand event loops.

We quickly looked at the basics of isolation, event loops, and asynchronous coding in Dart. For more detailed information, such as how microtask queues work, see the outdated but still beloved article event loops and Dart.

Original text: medium.com/dartlang/da…

Translation fgyong

Date 2020.7.28