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

  1. 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
  1. 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