flutter riverpod AsyncNotifier 和 Notifier

Flutter Riverpod:AsyncNotifier 与 Notifier 详细分析对比

一、核心概述

1. Notifier

  • 用途:同步状态管理

  • 适用场景:简单状态,不需要异步操作

  • 状态类型T(任意同步类型)

2. AsyncNotifier

  • 用途:异步状态管理

  • 适用场景:需要异步加载、保存数据(如API调用、数据库操作)

  • 状态类型AsyncValue<T>(包装异步状态)

二、详细对比分析

类定义对比

dart

复制代码
// Notifier - 同步
class CounterNotifier extends Notifier<int> {
  @override
  int build() {
    return 0; // 直接返回同步值
  }
}

// AsyncNotifier - 异步
class UserProfileNotifier extends AsyncNotifier<UserProfile> {
  @override
  FutureOr<UserProfile> build() async {
    // 可以执行异步操作
    return await _fetchUserProfile();
  }
}

状态类型对比

特性 Notifier AsyncNotifier
状态类型 T AsyncValue<T>
初始状态 直接值 AsyncLoading
错误处理 需手动处理 内置错误状态
加载状态 需手动管理 自动管理

AsyncValue 状态类型

dart

复制代码
AsyncValue<T> 有三种状态:
1. AsyncLoading - 加载中
2. AsyncData(T data) - 数据加载成功
3. AsyncError(Object error, StackTrace stackTrace) - 加载失败

三、使用场景详解

适合使用 Notifier 的场景

dart

复制代码
// 1. 计数器
class CounterNotifier extends Notifier<int> {
  @override
  int build() => 0;
  
  void increment() => state++;
  void decrement() => state--;
}

// 2. 简单的表单状态
class FormNotifier extends Notifier<FormData> {
  @override
  FormData build() => FormData.empty();
  
  void updateField(String field, String value) {
    state = state.copyWith(field: value);
  }
}

适合使用 AsyncNotifier 的场景

dart

复制代码
// 1. API数据获取
class ProductsNotifier extends AsyncNotifier<List<Product>> {
  @override
  Future<List<Product>> build() async {
    return await _fetchProducts();
  }
  
  Future<void> refresh() async {
    state = const AsyncValue.loading();
    state = await AsyncValue.guard(() => _fetchProducts());
  }
  
  Future<void> addProduct(Product product) async {
    final newProduct = await _api.addProduct(product);
    state = AsyncValue.data([...state.value!, newProduct]);
  }
}

// 2. 用户认证
class AuthNotifier extends AsyncNotifier<User?> {
  @override
  Future<User?> build() async {
    return await _checkSavedToken();
  }
  
  Future<void> login(String email, String password) async {
    state = const AsyncValue.loading();
    state = await AsyncValue.guard(() => _performLogin(email, password));
  }
}

四、方法对比

Notifier 核心方法

dart

复制代码
abstract class Notifier<T> {
  T build();  // 必须实现,返回初始状态
  T get state; // 当前状态
  set state(T value); // 设置新状态
  void update((T state) => T cb); // 基于当前状态更新
}

AsyncNotifier 核心方法

dart

复制代码
abstract class AsyncNotifier<T> {
  FutureOr<T> build(); // 可以返回 Future
  AsyncValue<T> get state;
  set state(AsyncValue<T> value);
  
  // 特有方法
  Future<void> update((T? state) => FutureOr<T> cb);
  Future<T> future; // 获取 build 返回的 Future
}

五、UI 中使用对比

Notifier 在 UI 中的使用

dart

复制代码
final counterProvider = NotifierProvider<CounterNotifier, int>(
  CounterNotifier.new,
);

Consumer(
  builder: (context, ref, child) {
    final count = ref.watch(counterProvider);
    return Text('Count: $count');
  },
)

AsyncNotifier 在 UI 中的使用

dart

复制代码
final productsProvider = AsyncNotifierProvider<ProductsNotifier, List<Product>>(
  ProductsNotifier.new,
);

Consumer(
  builder: (context, ref, child) {
    final productsAsync = ref.watch(productsProvider);
    
    return productsAsync.when(
      loading: () => CircularProgressIndicator(),
      error: (error, stack) => ErrorWidget(error),
      data: (products) => ListView.builder(
        itemCount: products.length,
        itemBuilder: (context, index) => ProductItem(products[index]),
      ),
    );
  },
)

六、错误处理对比

Notifier 错误处理(需手动)

dart

复制代码
class ManualErrorNotifier extends Notifier<Result<int>> {
  @override
  Result<int> build() => Result.success(0);
  
  void riskyOperation() {
    try {
      final result = _doSomethingRisky();
      state = Result.success(result);
    } catch (e) {
      state = Result.failure(e);
    }
  }
}

AsyncNotifier 错误处理(自动)

dart

复制代码
class AutoErrorNotifier extends AsyncNotifier<int> {
  @override
  Future<int> build() async {
    // 自动捕获异常并转为 AsyncError
    return await _fetchData();
  }
  
  Future<void> retry() async {
    // AsyncValue.guard 自动处理错误
    state = await AsyncValue.guard(() => _fetchData());
  }
}

七、性能与最佳实践

性能考虑

  1. Notifier:更轻量,适合频繁更新的状态

  2. AsyncNotifier:稍重,但提供了完整的异步状态管理

最佳实践

何时选择 Notifier
  • 状态同步且简单

  • 不需要加载/错误状态

  • 状态更新频繁

  • 本地状态管理

何时选择 AsyncNotifier
  • 需要异步初始化

  • 需要处理加载状态

  • 需要内置错误处理

  • 与API/数据库交互

  • 复杂的数据流管理

混合使用示例

dart

复制代码
// 使用 AsyncNotifier 处理数据获取,Notifier 处理 UI 状态
final userProvider = AsyncNotifierProvider<UserNotifier, User>(
  UserNotifier.new,
);

final themeProvider = NotifierProvider<ThemeNotifier, ThemeData>(
  ThemeNotifier.new,
);

// 在业务逻辑中结合使用
class UserDashboardNotifier extends Notifier<DashboardState> {
  @override
  DashboardState build() {
    // 监听异步用户数据
    final userAsync = ref.watch(userProvider);
    final theme = ref.watch(themeProvider);
    
    return userAsync.when(
      loading: () => DashboardState.loading(theme),
      error: (e, _) => DashboardState.error(e, theme),
      data: (user) => DashboardState.success(user, theme),
    );
  }
}

八、迁移示例

从 Notifier 迁移到 AsyncNotifier

dart

复制代码
// 之前:手动管理加载状态
class OldUserNotifier extends Notifier<UserState> {
  @override
  UserState build() => UserState.loading();
  
  Future<void> loadUser() async {
    state = UserState.loading();
    try {
      final user = await api.getUser();
      state = UserState.success(user);
    } catch (e) {
      state = UserState.error(e);
    }
  }
}

// 之后:使用 AsyncNotifier
class NewUserNotifier extends AsyncNotifier<User> {
  @override
  Future<User> build() => api.getUser();
  
  Future<void> refresh() async {
    state = const AsyncValue.loading();
    state = await AsyncValue.guard(() => api.getUser());
  }
}

总结

维度 Notifier AsyncNotifier
复杂度 简单 中等
异步支持 需手动处理 内置支持
状态管理 同步状态 异步状态包装
错误处理 手动 自动
加载状态 手动 自动
适用场景 简单同步状态 异步数据流
性能 更轻量 稍重但功能全

选择建议

  • 如果状态完全是同步的,不需要加载/错误状态 → 使用 Notifier

  • 如果涉及异步操作(API、数据库等) → 使用 AsyncNotifier

  • 对于复杂应用,通常需要混合使用两者

相关推荐
不爱吃糖的程序媛2 小时前
如何判断Flutter三方库是否需要OHOS适配开发?附完整适配指导
flutter·华为·harmonyos
kirk_wang3 小时前
Flutter艺术探索-Flutter渲染管道:RenderObject与Layer深度解析
flutter·移动开发·flutter教程·移动开发教程
微祎_3 小时前
Flutter for OpenHarmony:构建一个 Flutter 点击狂热游戏,深入解析响应式交互、动态反馈与高性能状态管理
flutter·游戏·交互
晚霞的不甘3 小时前
Flutter for OpenHarmony实现高性能流体粒子模拟:从物理引擎到交互式可视化
前端·数据库·经验分享·flutter·microsoft·计算机视觉
晚霞的不甘3 小时前
Flutter for OpenHarmony 流体气泡模拟器:用物理引擎与粒子系统打造沉浸式交互体验
前端·flutter·ui·前端框架·交互
一起养小猫3 小时前
Flutter for OpenHarmony 实战:打造功能完整的记账助手应用
android·前端·flutter·游戏·harmonyos
一起养小猫3 小时前
Flutter for OpenHarmony 实战:打造功能完整的云笔记应用
网络·笔记·spring·flutter·json·harmonyos
微祎_4 小时前
Flutter for OpenHarmony:构建一个 Flutter 旋转迷宫游戏,深入解析网格建模、路径连通性检测与交互式解谜设计
javascript·flutter·游戏
一起养小猫4 小时前
Flutter for OpenHarmony 实战:笔记应用文件操作与数据管理详解
flutter·harmonyos