preface
Many people feel that the Future in flutter is the same as the Promise in JavaScript, but the system description only uses a simple async and await. In fact, they have the same principle and similar use methods
Async/await is really just a use of Future or Proimise, but it’s not obvious
Future
Future and async and await
If we define a method and compare the definition of an asynchronous function, we’ll see that the two are the same thing
// Define two methods, one with a return value and one without
Future<int> getUserInfo() async {
print(789);
return 1;
}
//Future getUserInfo2() async is the same as below
getUserInfo2() async {
print(123);
return 2;
}
// Test method
testGetUserInfo() {
final user1 = getUserInfo();
print(user1);
final user2 = getUserInfo2();
print(user2);
}
testGetUserInfo2() async {
final user1 = await getUserInfo();
print(user1);
final user2 = await getUserInfo2();
print(user2);
}
Copy the code
After executing the two test codes separately, the following results are returned
/ / testGetUserInfo execution
789
Instance of 'Future<int>'
123
Instance of 'Future<dynamic>'
/ / testGetUserInfo2 execution
789
1
123
2
Copy the code
The test results further show that the two functions return a Future object by default, where the function that does not return a value returns a Future object whose generic type is arbitrary Dynamic
If an await is used, the function will block execution until the execution inside the await completes and the result is returned
As mentioned earlier, the “await” function is blocked and put in a queue to delay execution. After all, the flutter mode is single-threaded and the Future is just emulating multi-threaded operations
The use of asynchronous functions
Having seen the relationship between Future and async above, let’s take a closer look at writing an asynchronous function
Async is an encapsulated Future function that returns a Future as a synchronous function, so you need to await it to get an asynchronous effect
//Future is similar to js Promise
Future delay1Second() async {
print("I want to sleep.");
sleep(Duration(seconds: 1));
print("Sleep over.");
}
// This code is exactly the same as above, except that the system automatically wraps a Future
Future delay1SecondReplace() {
return Future(() {
print("I'm gonna sleep on it.");
sleep(Duration(seconds: 1));
print("Ready to sleep.");
});
}
Copy the code
The above test results are not listed, as expected
Future advanced use
Promise was mentioned earlier, and Future can be used in the same way
If you need to process the result of some asynchronous function, you will not be able to use async and await
Here is a method that calls back a result asynchronously, in the form of a closure
// I called a third party, in the form of a closure, to call a result asynchronously
threeMethod(Function(int? result) completed) {
Future.delayed(Duration(seconds: 2), () {
print("I'm a three-way time consuming algorithm, and it takes about 2s to get something.");
// Take a random int with a maximum value of 10
if (Random().nextInt(10) % 10 > 4) {
completed(5);
}else {
completed(null); }}); }Copy the code
For those of you who have written javascript, this is something I can do with a Promise + resolve, Reject, such as the following
/ / Promise version
workThreeMethod() {
return Promise((resolve, reject) = > {
threeMethod((res) {
// Return null as an error
if (res == null) {
// You can also return completed without error, so there is no catch outside
reject(new Error("Calculation error, return an error, need outside catch"));
}else {
resolve(5); }})}); }Copy the code
But what if there is no Resolve, Reject in Future?
The system provides the Completer class, as shown below, and will find that, apart from eliciting one more object, it is too similar
workThreeMethod() {
// If you don't want to pass out the value, the generic type is void, otherwise use the specified type, or leave it blank (the default is dynamic)
final completer = Completer<int>();
threeMethod((res) {
// Return null as an error
if (res == null) {
// You can also return completed without error, so there is no catch outside
//await an error, crash,.catch
completer.completeError("Calculation error, return an error, need outside catch");
}else {
// return to result, await is result of callback here
completer.complete(5); }});return completer.future;// Finally return a future
}
Copy the code
The following is the correct call scenario, for errors
// This is a callback error
testWorkThreeMethod() {
workThreeMethod().then((res) {
print('res:${res}');
}).catchError((err) {
print('err:' + err);
});
}
// We can also write it this way, so that the original error of the function will also be here
testWorkThreeMethod2() async {
try {
final res = await workThreeMethod();
print(res);
}catch(err) { print(err); }}Copy the code
As shown below, you can see that the two executions have the same result
I'm a three-way time consuming algorithm, and it takes about 2s to get a responseerr: calculation error, return an error, need outsidecatchHere I am a three-way time consuming algorithm, about 2s before the corresponding calculation error, return an error, need to outsidecatchtheCopy the code
Ps: The second one catches not only its own completeError, but also its own code’s error
The last
The principle of Future is the same as Promise, and if other languages have similar principles, you can try to see if similar things can be strung together
Also, the “All” and “Future” in Promise
For example, any in Future, which takes the Future array, returns a Future, and the result is an array type
After watching, is not the feeling very simple, come and try it