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

Riverpod Future Provider持续卡在加载状态问题求助

解决方案

1. 修正ref.read处理Future Provider的方式

ref.read获取Future Provider时,返回的是未绑定状态监听的AsyncValue,直接调用.when()只会执行当前初始的loading状态,不会自动更新。解决方式有两种:

方式一:在回调中手动await Future结果

如果是在按钮点击这类回调里,直接通过.future属性获取Future并await:

onPressed: () async {
  try {
    // 获取getPatient的结果
    final patientData = await ref.read(getPatientProvider(r.api_token).future);
    patientData.fold(
      (l) => print("something wrong happened"),
      (r) async {
        print(r.id);
        print("hello");
        // 更新patient状态
        patient.value = patient.value.copyWith(
          name: r.name,
          aliid: r.id,
          appointments: r.patient_appointments,
          fcmtoken: token,
        );
        // 同样处理docexist Provider
        final docData = await ref.read(docexist(r.id).future);
        if (docData.isEmpty) {
          print("data is not empty");
        } else {
          print("logged in normally");
        }
      },
    );
  } catch (err) {
    print(err);
  }
},

方式二:在Widget build中用ref.watch监听状态

如果是在Widget的build方法内,直接用ref.watch监听Provider的状态变化,它会自动重建Widget更新状态:

@override
Widget build(BuildContext context, WidgetRef ref) {
  final patientAsync = ref.watch(getPatientProvider(r.api_token));
  return patientAsync.when(
    loading: () => const CircularProgressIndicator(),
    error: (err, stack) => Text("Error: $err"),
    data: (patientData) {
      return ElevatedButton(
        onPressed: () {
          patientData.fold(
            (l) => print("something wrong happened"),
            (r) {
              // 处理数据逻辑
            },
          );
        },
        child: const Text("处理数据"),
      );
    },
  );
}

2. 检查docexist Provider的状态处理

原代码中调用ref.read(docexist(r.id)).when()的问题和上面一致,必须改用.futureawait结果,或者用ref.watch监听,否则永远停在loading状态。

3. 验证TaskEither的执行完整性

在getInfo方法中添加日志,确认TaskEither的run()方法返回的Future是否正常完成:

@override
Future<Either<ApiFailures, dynamic>> getInfo(String token) {
  var dio = Dio();
  final result = TaskEither<ApiFailures, PatientModel>(() async {
    // ... 原有代码
  });
  final futureResult = result.map((r) => r).run();
  // 添加日志验证
  futureResult.then((value) {
    print("getInfo执行完成: $value");
  }).catchError((err) {
    print("getInfo执行出错: $err");
  });
  return futureResult;
}

4. 确认Provider依赖的正确性

确保patientRepositoryProvider是普通的Provider类型(而非FutureProvider),且没有内部阻塞逻辑导致Future无法完成。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:35:27