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

Flutter & Riverpod:如何在Provider中使用.when方法

问题解决:The method when isn't defined for the type Future

错误原因

你直接调用了bluetoothServiceProvider.notifier.discoverDevices(),这个方法返回的是Future<List<Device>>类型,而.when()是Riverpod中AsyncValue类的专属方法,因此会出现该错误。正确的做法是让Provider维护异步操作的状态,通过监听Provider的状态来使用.when()处理加载、成功、错误场景。

修改后的服务类代码

part 'bluetooth_manager.g.dart';

@riverpod
class BluetoothService extends _$BluetoothService {
  @override
  AsyncValue<List<Device>> build() {
    // 初始状态设为空数据,可根据需求改为加载中
    return const AsyncValue.data([]);
  }

  Future<void> discoverDevices() async {
    try {
      // 更新状态为加载中
      state = const AsyncValue.loading();
      // 模拟设备扫描逻辑,替换为实际蓝牙扫描代码
      await Future.delayed(const Duration(seconds: 5));
      final devices = <Device>[/* 扫描得到的设备列表 */];
      // 更新状态为成功数据
      state = AsyncValue.data(devices);
    } catch (error, stacktrace) {
      // 更新状态为错误
      state = AsyncValue.error(error, stacktrace);
    }
  }
}

修改后的视图层代码

class ModulesView extends ConsumerStatefulWidget {
  const ModulesView({Key? key}) : super(key: key);

  @override
  ConsumerState<ModulesView> createState() => _ModulesViewState();
}

class _ModulesViewState extends ConsumerState<ModulesView> {
  @override
  void initState() {
    super.initState();
    // 在页面初始化后触发设备扫描,也可改为按钮点击触发
    WidgetsBinding.instance.addPostFrameCallback((_) {
      ref.read(bluetoothServiceProvider.notifier).discoverDevices();
    });
  }

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // 监听Provider的状态,获取AsyncValue对象
    final bluetoothState = ref.watch(bluetoothServiceProvider);

    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 12),
        child: bluetoothState.when(
              data: (data) => modulesFound(ref, data),
              loading: () => loading(),
              error: (error, stacktrace) => ErrorView(
                errorMessage: error.toString(),
                retryFunction: () => ref.read(bluetoothServiceProvider.notifier).discoverDevices(),
              ),
            ),
      ),
    );
  }
}

核心调整说明

  • 服务类build()方法返回AsyncValue<List<Device>>,用于维护异步操作的三种状态:加载中、成功、错误。
  • discoverDevices()不再直接返回Future,而是通过更新Provider的state来同步状态变化,让视图层可以监听。
  • 视图层通过ref.watch(bluetoothServiceProvider)获取AsyncValue实例,此时即可正常调用.when()方法处理不同状态。
  • 扫描触发逻辑移至initState(或按钮点击事件),避免build方法重复执行扫描操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 00:07:46