1 Asynchronous programming
1.1Future
factory Future(FutureOr<T> computation()) {
_Future<T> result = new _Future<T>();
Timer.run(() {
try {
result._complete(computation());
} catch (e, s) {
_completeWithErrorCallback(result, e, s);
}
});
return result;
}
The Future class represents the result of an asynchronous operation. Dart is single-threaded , so there is no such thing as a lock at the bottom layer, but this does not mean that Dart cannot be asynchronous, and asynchrony does not mean multi-threading.
1.2 async、await
Future is used for asynchronous execution, and the combination of async and await is used to execute a block of code in Future synchronously .
1.3 Future.then()
Future的所有API的返回仍是个Future对象,所以可使用Future进行链式调用。
Use then to put specific tasks that need to wait, and then do not block the execution of subsequent tasks. If then does not return a value, then value is null.
1.4 Future.catchError
1.5 Comprehensive use of Future
1.6 Future.wait
Wait until all tasks in wait are completed before executing then
1.7 microtask
In the Dart event loop, there are two queues:
- Event queue (event queue) - all external events: I/O, mouse events, drawing events, timers, information transfer between isolates.
- Microtask queue (microtask queue) - an asynchronous task that will be completed in a short period of time. It has the highest priority , and as long as there are tasks in the queue, it can always occupy the event loop. If there are too many microtasks to be processed in the microtask queue, external events such as touch and drawing may be blocked.
As shown in the figure below (the picture is reproduced from LinShunIos )
2. Multithreading
2.1 isolate
If func is executed in Isolate, there will be different results
run multiple tasks
It can be seen that Isolate performs tasks in sub-threads .
The isolate in Dart has an independent memory space, the data in each isolate is independent, there is no resource grabbing , and no lock is required. Therefore, it cannot be accessed directly when accessing the isolated data . Isolate is actually a lightweight process. It does not open up the heap and stack independently, but gives a local memory space, and all variables and memory objects are in this space. Inter-process communication is required when the isolate communicates with the original program .
Run and find that the value of a has not changed. If you want to change the value of a, you need to use the port, pass the sendPort of the port as a parameter to func, and then add monitoring data changes to receive the value passed from func.
In this way, the value of a is changed. Since Isolate has opened up space, Isolate needs to be destroyed manually. await will not block the execution of the following code, because it is in other threads .
2.2 compute
Compute can return data and modify the value of data, adding await will block the following code
3. Asynchronous and multi-threaded combination
The following code is executed asynchronously
Make a slight change and find that it is synchronous
The arrow function hides the return, so the difference above is that one has a return and the other does not. If there is a return (that is, the sub-thread is returned), then processes the result of the sub-thread Future; otherwise, it is the result of the current Future
void isoLoadDemo() {
Future(() {
print('1开始');
return compute(testfunc, 123);
}).then((value) => {print('1结束')});
Future(() {
print('2开始');
return compute(testfunc, 123);
}).then((value) => {print('2结束')});
Future(() {
print('3开始');
return compute(testfunc, 123);
}).then((value) => {print('3结束')});
Future(() {
print('4开始');
return compute(testfunc, 123);
}).then((value) => {print('4结束')});
Future(() {
print('5开始');
return compute(testfunc, 123);
}).then((value) => {print('5结束')});
}
flutter: 1开始
flutter: 2开始
flutter: 3开始
flutter: 4开始
flutter: 5开始
flutter: 1结束
flutter: 2结束
flutter: 5结束
flutter: 3结束
flutter: 4结束
4. Time-consuming operations are executed asynchronously in sub-threads
void _incrementCounter() {
Future(() => compute(testfunc, 100));
setState(() {
_counter++;
});
}
FutureOr testfunc(int message) {
print('开始');
for(int i = 0; i < 10000000000; i++) {
}
print('结束了');
}