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

使用Flutter Riverpod等待Future解析时显示CircularProgressIndicator异常排查

问题分析与解决方案

原代码的核心问题

  1. 页面提前销毁:触发异步操作后立刻调用Navigator.pop(),当前页面被直接关闭,FutureBuilder根本没机会渲染加载状态。
  2. 状态管理混乱:rejectResponse是局部变量,FutureBuilder初始化时该变量未赋值,后续赋值后调用setState但页面已被弹出,完全无效。
  3. Riverpod与FutureBuilder搭配不当:没有利用Riverpod的状态管理能力,反而用局部变量+FutureBuilder的方式,状态不可控且容易出错。

推荐解决方案:用StateNotifier管理异步状态(符合Riverpod最佳实践)

这种方式把异步操作的状态交给Riverpod统一管理,逻辑更清晰,状态更稳定。

第一步:创建StateNotifier处理审批状态

// 定义Provider
final approveDocumentProvider = StateNotifierProvider<ApproveDocumentNotifier, AsyncValue<void>>((ref) {
  final repo = ref.watch(notificationRepositoryProvider);
  return ApproveDocumentNotifier(repo);
});

// 状态管理类
class ApproveDocumentNotifier extends StateNotifier<AsyncValue<void>> {
  final NotificationRepository _repo;

  ApproveDocumentNotifier(this._repo) : super(const AsyncData(null));

  Future<void> approve(int documentId) async {
    // 标记为加载状态
    state = const AsyncLoading();
    try {
      await _repo.approveDocument(documentId);
      // 操作成功,重置为无数据状态
      state = const AsyncData(null);
    } catch (e) {
      // 操作失败,记录错误状态
      state = AsyncError(e, StackTrace.current);
    }
  }
}

第二步:在ConsumerStatefulWidget中使用

ElevatedButton(
  onPressed: () async {
    final notifier = ref.read(approveDocumentProvider.notifier);
    // 等待异步操作完成后再关闭页面
    await notifier.approve(1);
    Navigator.of(context).pop();
  },
  child: ref.watch(approveDocumentProvider).when(
        data: (_) => const Text('Yes'),
        loading: () => const CircularProgressIndicator(),
        error: (_, __) => const Text('Error'),
      ),
)

临时修复方案:调整现有代码逻辑(不推荐长期使用)

如果不想新增StateNotifier,可以修改原代码逻辑,确保页面在异步操作完成后再关闭:

// 在State类中定义Future变量
Future<void>? _approveFuture;

// ...

ElevatedButton(
  onPressed: () {
    setState(() {
      // 赋值Future并触发重绘
      _approveFuture = ref.read(notificationRepositoryProvider).approveDocument(1);
    });
    // 等待异步操作完成后再关闭页面
    _approveFuture?.then((_) {
      Navigator.of(context).pop();
    }).catchError((error) {
      // 可选:错误时的处理,比如留在页面显示错误
      // setState(() {});
    });
  },
  child: FutureBuilder(
    future: _approveFuture,
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) {
        return const CircularProgressIndicator();
      } else if (snapshot.hasError) {
        return const Text('Error');
      }
      return const Text('Yes');
    },
  ),
)

内容的提问来源于stack exchange,提问作者DEPARTED

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:30:39