You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Riverpod的SelectedAccount Provider始终卡在AsyncLoading状态求助

问题分析与解决

核心问题

你的SelectedAccount Provider无限停留在AsyncLoading状态的根源在于build方法返回的Future.any([])会无限期挂起。Future.any([])需要等待传入的Future列表中任意一个完成,但空列表没有可完成的Future,导致这个Future永远不会resolve,Provider始终处于初始加载状态,后续调用select时的状态更新被这个未完成的初始Future干扰,无法切换到AsyncData。

解决方案

  1. 替换build方法的无效返回值
    去掉永远pending的Future.any([]),改为符合业务需求的初始值:

    • 如果初始没有选中的账户,可将状态类型改为Account?并返回null(同步返回,无需异步)
    • 如果需要初始异步加载默认账户,确保Future能正常完成(比如捕获异常返回默认值)
  2. 修正后的示例代码

@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:57:19