前言:
问题1:在shared_preferences存储着是否登录的状态,然后根据状态决定跳转的页面,但获取该状态是异步,而页面需要同步方式获取Weight。
解决:对shared_preferences在页面运行前进行初始化,将异步转换为同步。
class SpUtil {
static SharedPreferences _sp;
static Future init() async{
_sp = await SharedPreferences.getInstance();
}
//获取String、int、double、bool、List<String>类型
static dynamic get(String key) async {
return _sp.get(key);
}
}
问题2:如果在APP页面运行前有多个初始化的操作,考虑到启动时间需要将这些初始化操作并发执行,当都初始化完成后才运行APP页面
解决:以下是错误做法,Future并不能达到多并发(具体原因见Future),但这里考虑到SP初始化必须要在主Isolate中进行,暂且这样处理
//声明初始化函数类型
typedef InitFunction = Future Function();
void main() {
List<InitFunction> initFunctionList = new List();
//添加初始化函数
for(int a = 0; a < 5; a++){
initFunctionList.add(() {
return init(a);
});
}
//参数1为初始化函数集合,参数2为所有初始化完成后执行函数
initFunction(initFunctionList, () {
runApp(MyApp());
});
}
//初始化函数
Future init(int a) async{
print("****第" + a.toString() + "开始");
await Future.delayed(Duration(seconds: 10 - a));
print("****第" + a.toString() + "结束");
}
void initFunction(List<InitFunction> initFunctionList,
Function finishFunction) {
int totalNum = initFunctionList.length;
int finishedNum = 0;
for (int i = 0; i < totalNum; i++) {
print("****循环:" + i.toString());
//进行初始化
initFunctionList[i]().then((value) {
//校验所有初始化函数是否全部完成
finishedNum++;
if (finishedNum == totalNum) {
print("****完成");
finishFunction();
}
});
}
}
-----------------------------------------简化写法-------------------------------------
void main() {
//添加初始化函数
List<Future> initFunctionList = new List();
//添加初始化函数
for (int a = 0; a < 5; a++) {
initFunctionList.add(initFunction(a));
}
Future.wait(initFunctionList).then((value) {
print("****完成");
runApp(MyApp());
});
}
Future initFunction(int a) async {
print("****第" + a.toString() + "开始");
await Future.delayed(Duration(seconds: 10 - a));
print("****第" + a.toString() + "结束");
}
正文:async/await即挂起式(非阻塞式):async标记的方法当执行到await时该方法挂起,跳出该方法继续执行,await执行完成则执行其后的代码。【同步方式编写异步代码】
一、方法中存在await标识则该方法必须加async标识,即该方法中需要等待则肯定是异步的
二、方法加async标识但方法中不一定存在await标识,即该方法为异步但未必存在异步操作
三、async标识的方法返回值必为Future类型,如果没有写类型则默认返回Future<dynamic>类型
四、嵌套执行顺序:main--》parent await--》children await--》main--》children await 之后--》parent await之后
void main() {
print("开始");
parent();
print("结束");
}
Future parent() async{
print("父:开始");
await children();
print("父:结束");
}
children() async{
print("子:开始");
await Future.delayed(Duration(seconds: 4));
print("子:结束");
}
四、一个方法中可以存着多个await
main() async {
await funA();
await funB();
}
五、顺序执行,如上可以简化如下
main() async {
new Future(funA).then((value) => funB());
}
六、先并发,都完成后再顺序执行。已在前言问题2中封装的initFunction方法实现