通常,在编写应用程序时,我喜欢到处提到返回类型。这确保了我不会返回错误的对象,并在我还在编写代码时检查代码。
假设我正在ApiProvider中编写一个方法,该方法在成功的事件中返回一个用户对象。
即,
Future<UserModel> checkAuth (String username, String password) async {
final result = client.get (.............);
final UserModel model = UserModel.fromJson(result);
return model;
}
现在一切都很好,直到我引入了试图捕获块来处理错误。这将修改我的代码如下:
Future<UserModel> checkAuth (String username, String password) async {
try {
final result = client.get (.............);
final UserModel model = UserModel.fromJson(result);
return model;
} on Exception catch(e) {
return ErrorModel(e.statusCode, e.message);
}
}
现在,如您所见,如果出现错误,我必须返回一个错误模型,或者只返回字符串(e.message)。但是,我的函数只能返回UserModel的实例。我不想让返回类型变得动态,因为它使我的代码非常松散地耦合。
我怎样才能克服这个问题,是否有更好的方法来解决这个问题?通常,在获得api响应或错误响应之后,我会在流中填充结果,以便在UI上向用户显示结果。我利用集团建筑。
任何帮助都将不胜感激。提前感谢!
发布于 2022-07-26 18:52:03
您可以使用either_dart
包,它处理函数返回的“错误”L
和“成功”R
状态,而不需要显式声明基类。
以您的函数为例:
import 'package:either_dart/either.dart';
Future<Either<ErrorModel, UserModel>> checkAuth(String username, String password) async {
try {
final result = client.get (.............);
final UserModel model = UserModel.fromJson(result);
return Right(model);
} on Exception catch(e) {
return Left(ErrorModel(e.statusCode, e.message));
}
}
并利用它:
final Either<ErrorModel, UserModel> result = await checkAuth(...);
if (result.isLeft) {
// error...
final ErrorModel user = result.left;
} else if (result.isRight) {
// sucess...
final UserModel user = result.right;
}
您可以在BLoC
、Mobx
Store、Provider
之类的状态管理器类中处理它的结果,并将要呈现的正确文本发送给UI。所以:
// services/my_service_class.dart
class MyService {
Either<L, R> callSomeApi() { }
}
// store/my_ui_manager_class.dart
class MyUIStateManagerClass extends BLoC {
final MyService service = MyService();
Future<void> callSomething() async {
final result = await service.callSomeApi();
if (result.isLeft) {
// error...
final ErrorModel user = result.left;
} else if (result.isRight) {
// sucess...
final UserModel user = result.right;
}
}
}
// widgets/my_ui_class.dart
class MyWidget {
MyUIStateManagerClass stateManager;
void initState() {
super.initState();
stateManager = MyUIStateManagerClass();
stateManager.callSomething();
}
Widget build(BuildContext context) {
return ...
}
}
发布于 2022-07-26 18:58:07
使用例外情况:
class ApiProviderException implements Exception {
final int? statusCode;
final String? message;
ApiProviderException(this.statusCode, this.message);
@override
String toString() {
return '$statusCode - $message';
}
}
...
Future<UserModel> checkAuth(String username, String password) async {
try {
final result = client.get (.............);
final UserModel model = UserModel.fromJson(result);
return model;
} on Exception catch (e) {
throw ApiProviderException(e.statusCode, e.message);
}
}
使用它:
try {
final model = await checkAuth(username, password);
// some code
} on ApiProviderException catch (e) {
// some code
}
https://stackoverflow.com/questions/73128200
复制相似问题