一、什么是回调地狱(Callback Hell)?
“回调地域”指的是,多级的异步的嵌套调用的问题。
举个例子:1、用户先登录 ,登录成功后会获得用户ID ---> 2、然后通过用户ID,再去请求用户个人信息,获取到用户个人信息后 ---> 3、为了使用方便,我们需要将其缓存在本地文件系统。 ---> 4、保存成功后,显示主页面逻辑
// 1 先分别定义各个异步任务
Future<String> login(String userName, String pwd){
...
//用户登录
};
Future<String> getUserInfo(String id){
...
//获取用户信息
};
Future saveUserInfo(String userInfo){
...
// 保存用户信息
};
// 1、登录
login("alice","******").then((id){
// 2、获取用户信息
getUserInfo(id).then((userInfo){
// 3、保存用户信息
saveUserInfo(userInfo).then((){
// 4、显示主页面逻辑
showMainPageView();
});
});
})
看到上面的例子,做过客户端开发的并不陌生,其本质是短时间内存在多种业务逻辑,业务逻辑之间有存在一定的先后顺序。特别是现在服务端讲究微服务治理,将服务进行划分细化到不同的服务器中,这样原来一个接口 可能变成 多个串行的接口调用。
二、Dart 如何解决回调地域呢?
1、链式编程解决和消除Callback Hell
利用链式编程的调用特点,可以很容易的将 内部的嵌套调用 剥离到 顶层,然后通过点.操作符进行链接。
- 下面是
Future
异步框架的解决方案
由于Future
所有的接口都会返回Future
对象,可以简单的利用链式编程可解决嵌套问题。
// 1、登录
login("alice","******").then((id){
// 2、获取用户信息
return getUserInfo(id);
}).then((userInfo){
// 3、保存用户信息
return saveUserInfo(userInfo);
}).then((e){
// 4、显示主页面逻辑
showMainPageView();
}).catchError((e){
// 4、错误处理
print(e);
});
3、消除 callback hell
- 利用
task() async {
try{
// 1、登录
String id = await login("alice","******");
// 2、获取用户信息
String userInfo = await getUserInfo(id);
// 3、保存用户信息
await saveUserInfo(userInfo);
// 4、显示主页面
showMainPageView();
} catch(e){
// 4、错误处理
print(e);
}
}
和Future 不同的是,它可以接收多个异步操作的结果(成功或失败)。 也就是说,在执行异步任务时,可以通过多次触发成功或失败事件来传递结果数据或错误异常。 Stream 常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等。
Stream.fromFutures([
Future.delayed(Duration(seconds: 1), (){
return 'result 1';
}),
Future.delayed(Duration(seconds: 2), (){
throw AssertionError('sorry!');
}),
Future.delayed(Duration(seconds: 3), (){
return 'result 2';
})
]).listen((event) {
print('listen: $event');
}, onError: (e){
print('err: $e');
}, onDone: (){
print('finish!');
});
// 打印
listen: result 1
err: Assertion failed: "sorry!"
listen: result 2
finish!
网友评论