I strongly recommend taking a look at Dart asynchronous programming first
Future
Future represents a value or error at a later time. This is implemented with Future in Flutter
A Future has two states:
- The execution of
- Completion of execution (both successes and failures)
The Future follow-up Api
Let’s take a look at the Future follow-up
Main (){Future(){return 'hello '; }). Then ((value) {print(value); Print ('catchError'); }) print('catchError'); // print('catchError'); }). WhenComplete ((){print('whenComplete'); }); }Copy the code
The results of
Hello catchError whenCompleteCopy the code
The Future common API
Future.value()
Return a Future object with a value
main() { print('start'); Future.value(' future.value '). Then ((value) => print(value)); print('end'); }Copy the code
The results of
Start end hahahaCopy the code
Future.error() creates a Future with an error completion state (can carry any type of value)
main() { print('start'); Future.error(Exception(" error ")).then((value) => print(value)).catchError((e){print(e.tostring ())); }); print('end'); }Copy the code
The results of
Start end Exception: An Exception occursCopy the code
How long has been future.delayed () (The time may not be exact, it may not be the time delayed if the last task was a time-consuming operation)
main() { print('start'); Future.delayed(Duration(seconds: 2),(){return 'delayed two seconds '; }).then((value){ print(value); print(DateTime.now().second); }).catchError((e){ print(e.toString()); }); print('end'); print(DateTime.now().second); }Copy the code
The results of
Start end 11 Delay of 2 seconds 13Copy the code
So if I add a little bit
Future((){
sleep(Duration(seconds: 5));
}).then((value) => print(DateTime.now().second));
Copy the code
The result is 5s execution
Start end 9 14 Delay of 2 seconds 14Copy the code
Future.wait([] futures)
Wait for all futures to complete and then return together. If any future fails during the process, the whole task fails
Main () {future.wait ([future.value (" hahaha ")), future.value (222), future.delayed (Duration(seconds: 2)) ]) .then((value) => print(value)); }Copy the code
The results of
[hahaha, 222, null]Copy the code
There is a Future error
main() { Future.wait([ Future.delayed(Duration(seconds: 2)), Future.error(222), ]) .then((value) => print(value)) .catchError((e){print("catchError"); }); }Copy the code
The entire mission failed.
catchError
Copy the code
Future.microtask
If you’ve seen the link at the top of this article, you know that MicroTasks take precedence over events. When non-future code is executed, microTasks are queued, processed, and events are queued
main() { Future((){print("0000000"); }).then((value) => print('11111111')); Future.value('2222222').then((value) => print(value)); Future.microtask(() =>print("3333333")).then((value) => print('444444444')); }Copy the code
The execution result
2222222
3333333
444444444
0000000
11111111
Copy the code
Ah? Why is future.value () faster than Future.microTask? Look at the source code, there is a key sentence
. There's a bunch of calls up there, omitting... void _asyncCompleteWithValue(T value) { _setPendingComplete(); _zone.scheduleMicrotask(() { _completeWithValue(value); }); }Copy the code
So future.value () and future.error () are microtasks, so…
Future.sync()
Execute immediately… It’s the same as synchronizing code
main() { Future((){print("0000000"); }).then((value) => print('11111111')); Future.value('2222222').then((value) => print(value)); Future.microtask(() =>print("3333333")).then((value) => print('444444444')); Future.sync(() => print("55555555")); }Copy the code
The results of
55555555
2222222
3333333
444444444
0000000
11111111
Copy the code
When the main function starts executing, line 1 sends an event, line 2 sends a microtask, line 3 sends a microtask, and line 4 executes immediately, so the result is as above
Future.any([])
Then () is the result of the Future, and if the list fails to complete it first, it will be called back to then()
main() {
Future.any([
Future.value('0000000'),
Future.value('11111111'),
// Future.error("2222222")
])
.then((value) => print(value));
}
Copy the code
The results of
0000000
Copy the code
Future.forEach()
main() {
Future.forEach([
Future.error("2222222"),
Future.value('0000000'),
Future.value('11111111'),
], (element) => print(element)).catchError((e){
print('catchError');
}).whenComplete(() => print('whenComplete'));
}
Copy the code
The results of
Instance of 'Future<dynamic>'
Instance of 'Future<String>'
Instance of 'Future<String>'
Unhandled exception:
2222222
Copy the code
Future.while()
Stop execution when false is returned
main() {
Future.doWhile((){
print('1111111');
Future.value('0000000');
Future.value('11111111');
return false;
});
}
Copy the code
1111111
Copy the code
Async and await
Async and await are syntactic sugar for future-related apis
- Async functions will typically return a Future object,
- Await is to perform asynchronous operations with synchronous code
- An async field must be added to a function using an await field
Let’s start with an example of wechat login
main() { getWxInfo() .then((value) => getUserInfo(value)) .then((value) => saveUserDate(value)) .then((value) => print(value)); } Future getWxInfo(){return future.value (" get wechat UID"); } Future getUserInfo(String param){return future. value("$param-> getUserInfo "); } Future saveUserDate(String param){return future. value("$param-> store user information "); }Copy the code
The results of
Obtained wechat UID-> obtained user information -> stored user informationCopy the code
Use async and await fields
main() async { String uid= await getWxInfo(); String uinfo=await getUserInfo(uid); String save=await saveUserDate(uinfo); print(save); } Future getWxInfo(){return future.value (" get wechat UID"); } Future getUserInfo(String param){return future. value("$param-> getUserInfo "); } Future saveUserDate(String param){return future. value("$param-> store user information "); }Copy the code
The result, of course, is asynchronous programming using synchronous code
Will the single-threaded Dart language stall? Why doesn’t it feel stuck at all now?
Dart’s IO operations are handed over to the runtime and the system, and threads are not blocked for file reading and writing, network requests, and can be blocked…. when there is a lot of data processing, such as complex JSON data parsing and massive data model transformation
Of course, there are solutions….. It’s called ISOLATE. Check out the link below
Understand Dart asynchrony and Isolate encapsulation
HTTP requests in Flutter
Dio project introduction address
Dio is a popular third-party HTTP library at present. It borrows Okhttp ideas in many places and is relatively easy to use. Just look at the Api on the official website, and I will open source a Dio-based package after I understand this content deeply
FutureBuilder
- Create a Future object (code is not important)
Future<HomeTest> _post() async {
Map<String ,dynamic> json= await HttpManager()
.getAsync(
url: '/posts/1',
options:
RequestOptions(baseUrl: 'https://jsonplaceholder.typicode.com'),
responseFormat: null);
return HomeTest.fromJson(json);
}
Copy the code
- Using futurebuilder
Container( height: 800, child: FutureBuilder<HomeTest>(future: _post(),builder: (BuildContext context, AsyncSnapshot<HomeTest> snapshot) { if(snapshot.connectionState==ConnectionState.none){ return Text('ConnectionState.none'); }else if(snapshot.connectionState==ConnectionState.waiting){ return Text('ConnectionState.waiting'); }else if(snapshot.connectionState==ConnectionState.active){ return Text('ConnectionState.active'); }else{return Text(' load complete --${snapshot.data}'); }},),)Copy the code
Populate different contents according to the state of AsyncSnapshot execution,
It is important to note, however, that if the parent node and other nodes call setState() before reloading the Futurebuilder post request, you have recreated the Futurebuilder, so control the state and location
The local store
Store some simple key-values locally in Flutter based on the shared_preferences plugin
Shared_preferences Project address
It’s also easier to use
Introduce into the project, synchronize the project download plug-in, import the corresponding package can be used
_testSharedPreferences() async { var sp = await SharedPreferences.getInstance(); await sp.setString("key1", 'value'); String value1=sp.get('key1'); String value2=sp.get('key2'); print('value1=$value1; value2=$value2'); }Copy the code
Note that the SharedPrefrences instance and setValue are retrieved asynchronously and the Future object is returned