回调地狱
如果代码中有大量的异步逻辑,并且这些请求有先后关系,可能后一个请求需要用到前一个请求的返回结果,那么就会出现**回调地狱,**例如用户登录的场景,首先需要用户登录,用户登录成功可以获得用户的id。通过用户的Id可以再去请求用户的个人信息,获得个人信息;为了使用的方便,我们一般还会把个人信息缓存在本地文件中,那么代码就会变成这样
java
//先分别定义各个异步任务
Future<String> login(String userName, String pwd){
...
//用户登录
};
Future<String> getUserInfo(String id){
...
//获取用户信息
};
Future saveUserInfo(String userInfo){
...
// 保存用户信息
};
//回调地狱
login("alice","******").then((id){
//登录成功后通过,id获取用户信息
getUserInfo(id).then((userInfo){
//获取用户信息后保存
saveUserInfo(userInfo).then((){
//保存用户信息,接下来执行其他操作
...
});
});
})
如何解决回调地狱呢?
Future的链式调用
可以使用Future的链式调用来消除,Future 的所有API的返回值仍然是一个Future对象。所以在调用then之后返回的结果还是一个Future,前一个then执行结束,就会触发后面的then回调,如此向下,避免了嵌套
java
login("alice","******").then((id){
return getUserInfo(id);
}).then((userInfo){
return saveUserInfo(userInfo);
}).then((e){
//执行接下来的操作
}).catchError((e){
//错误处理
print(e);
});
async/await
我们直到在kotlin中可以以编写同步代码的形式来执行异步任务,这大大的增加了代码的可读性,那么Dart是否支持呢?当然也是可以的。利用async和await,例如如下代码: async:用来表示函数(用于修饰函数)是异步的,它会返回一个Future对象 await:修饰的是一个Future,表示等待该异步任务完成,才会往后执行,注意await必须出现在async内部
java
task() async {
try{
String id = await login("alice","******");
String userInfo = await getUserInfo(id);
await saveUserInfo(userInfo);
//执行接下来的操作
} catch(e){
//错误处理
print(e);
}
}