使用Dartz如何在Either折叠时传递Failure并终止方法?
解决方案
完全可行,你可以通过**提前处理Either的左值(Failure)**来实现直接返回并终止执行,同时避免冗余的类型检查,保证代码健壮性。
方法一:提前判断左值(兼容所有Dart版本)
直接检查userResponse是否为左值,若是则立即返回,后续逻辑仅在右值(AuthUser)时执行:
class GetAuthUserUseCase { final AuthRepository _authRepository; GetAuthUserUseCase({ required AuthRepository authRepository, }) : _authRepository = authRepository; Future<Either<Failure, AuthUser>> call() async { final userResponse = await _authRepository.getUser(); // 遇到Failure直接返回,终止后续逻辑 if (userResponse.isLeft()) { return userResponse; } // 安全获取用户,无需类型检查(已确保是右值) final user = userResponse.getOrElse(() => throw UnreachableError()); final accessTokenExpiresAtMilliseconds = user.accessTokenIssuedAtMilliseconds + user.accessTokenExpiresInMilliseconds; final accessTokenExpiresAtDateTime = DateTime.fromMillisecondsSinceEpoch(accessTokenExpiresAtMilliseconds); if (DateTime.now().isBefore(accessTokenExpiresAtDateTime)) { return userResponse; } return _authRepository.refreshUser( user: user, ); } }
方法二:使用Dart 3+模式匹配(更优雅)
借助Dart 3的模式匹配语法,直接对Either的左右分支做处理,代码可读性更强:
class GetAuthUserUseCase { final AuthRepository _authRepository; GetAuthUserUseCase({ required AuthRepository authRepository, }) : _authRepository = authRepository; Future<Either<Failure, AuthUser>> call() async { final userResponse = await _authRepository.getUser(); switch (userResponse) { // 匹配Failure分支,直接返回 case Left(:final value): return Left(value); // 匹配AuthUser分支,执行后续逻辑 case Right(:final value): final user = value; final accessTokenExpiresAtMilliseconds = user.accessTokenIssuedAtMilliseconds + user.accessTokenExpiresInMilliseconds; final accessTokenExpiresAtDateTime = DateTime.fromMillisecondsSinceEpoch(accessTokenExpiresAtMilliseconds); if (DateTime.now().isBefore(accessTokenExpiresAtDateTime)) { return userResponse; } return _authRepository.refreshUser(user: user); } } }
核心优势
- 无类型检查冗余:通过提前分支处理,确保后续逻辑仅在拿到合法
AuthUser时执行,无需额外判断类型。 - 执行即时终止:遇到
Failure时直接返回,不会执行后续的过期检查等逻辑,符合需求。 - 代码健壮性:避免了原代码中
fold左分支可能出现的类型不匹配问题,逻辑更清晰。
内容的提问来源于stack exchange,提问作者anonymous-dev
相关产品推荐
相关产品推荐

