Riverpod的SelectedAccount Provider始终卡在AsyncLoading状态求助
问题分析与解决
核心问题
你的SelectedAccount Provider无限停留在AsyncLoading状态的根源在于build方法返回的Future.any([])会无限期挂起。Future.any([])需要等待传入的Future列表中任意一个完成,但空列表没有可完成的Future,导致这个Future永远不会resolve,Provider始终处于初始加载状态,后续调用select时的状态更新被这个未完成的初始Future干扰,无法切换到AsyncData。
解决方案
替换build方法的无效返回值
去掉永远pending的Future.any([]),改为符合业务需求的初始值:- 如果初始没有选中的账户,可将状态类型改为
Account?并返回null(同步返回,无需异步) - 如果需要初始异步加载默认账户,确保Future能正常完成(比如捕获异常返回默认值)
- 如果初始没有选中的账户,可将状态类型改为
修正后的示例代码
@riverpod class SelectedAccount extends _$SelectedAccount { // ignore: avoid_public_notifier_properties late final logger = ref.read(loggerProvider("logger_tag")); // 初始无选中账户,同步返回null(需将State类型改为Account?) @override Account? build() => null; Future<void> select(AccountSearchRecord account) async { state = const AsyncLoading(); logger.info("selecting $account"); logger.info("state $state"); state = await AsyncValue.guard(() async { final response = await ref.read(accountProvider(id: account.id).future); logger.info("$response"); return response; }); logger.info("state $state"); // 现在会输出AsyncData<Account> } }
如果业务要求初始状态必须是Account而非可空类型,可返回一个默认的空实例:
@override Account build() => Account.empty(); // 假设Account有empty()构造函数
额外说明
当AsyncNotifier的build方法返回的Future未完成时,Provider会一直保持初始的AsyncLoading状态,后续的状态更新操作可能无法正常生效。确保build方法的返回值能正常完成,是Provider状态正常流转的前提。
内容的提问来源于stack exchange,提问作者Dcow
相关产品推荐
相关产品推荐

