这一章学习异步的处理。在flutter里有很多操作都是异步的比如网络请求,或者读写数据库。
使用异步首先要导入异步库
import 'dart:async';
main(List<String> args) {
}
Future
异步库里有一个概念就叫 Future,future是基于观察者模式。类似于JavaScript里的Rx和Promise,如果属性这两个,就很容易理解future。
简单来说,Future定义了未来将要发生的事,例如:未来我们会得到一个值。
Future 是泛型,Future<T>,需要指定未来返回值的类型。如:
import 'dart:async';
main(List<String> args) {
getAJoke().then((value) {
print(value);
})
.catchError((error) {
print('Error');
});
}
Future<String> getAJoke() {
return new Future<String>(() {
//Do a long running task. E.g. Network Call.
//Return the result
return "This is a joke";
});
}
这里定义了一个getAJoke函数,返回值类型是Future<String>,函数内new了一个Future,Future构造函数接受一个返回T类型值的函数(这里是匿名函数),匿名函数返回的值就是future的返回值。
在main里调用getAJoke函数,并在then里定义里回调函数,当future有返回值的时候,回调函数被调用。这里还增加了catchError来处理Future执行时发生的错误
下面是错误处理的例子
import 'dart:async';
main(List<String> args) {
getAJoke().then((value) {
print(value);
})
.catchError((error) {
print('Error');
});
}
Future<String> getAJoke() {
return new Future<String>(() {
//Do a long running task. E.g. Network Call.
//Return the result
throw new Exception('No joke for you!');
return "This is a joke";
});
}
这个例子立刻返回了错误,但是在生产环境中,在Future里一般都是执行一些比较耗时的程序,例如网络请求,下面的例子用Future.delayed()模拟了网络请求
import 'dart:async';
main(List<String> args) {
getAJoke().then((value) {
print(value);
})
.catchError((error) {
print('Error');
});
}
Future<String> getAJoke() {
return new Future<String>.delayed(new Duration(milliseconds: 2000),() {
//Do a long running task. E.g. Network Call.
//Return the result
return "This is a joke";
});
}
可以看到2秒回打印了结果,看另一个例子
import 'dart:async';
main(List<String> args) {
getAJoke().then((value) {
print(value);
})
.catchError((error) {
print('Error');
});
print('Another print statement.');
}
Future<String> getAJoke() {
return new Future<String>.delayed(new Duration(milliseconds: 2000),() {
//Do a long running task. E.g. Network Call.
//Return the result
return "This is a joke";
});
}
上面代码中,在调用getAJoke后,我们增加了一行代码就是print这行。这种情况下,这个print先执行,然后才执行getAJoke里的print,这和预期的执行顺序一样,但是有时候需要先执行完异步,获得结果后再执行其它代码。这时候就需要async/await了
async/await
先看代码
import 'dart:async';
main(List<String> args) async {
try {
String result = await getAJoke();
print(result);
} catch(e) {
print(e);
}
print('Another print statement.');
}
Future<String> getAJoke() {
return new Future<String>.delayed(new Duration(milliseconds: 2000),() {
//Do a long running task. E.g. Network Call.
//Return the result
return "This is a joke";
});
}
上面的代码中,在main的大括号前 增加了async 关键字,在调用getAJoke前增加了await关键字。这样代码直到getAJoke有返回值时才会继续向下执行。同时调用的代码段放在了try/catch里,以便处理错误。需要说明的是,await必须放在有async 标识的函数里,才能执行。