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

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

相关推荐
Justin在掘金1 小时前
Flutter Riverpod 状态管理深入分析
flutter
Justin在掘金1 小时前
Flutter BLoC 状态管理框架深入分析
flutter
weixin_443478511 小时前
flutter组件学习之Cupertino 组件(iOS风格)
学习·flutter·ios
国医中兴2 小时前
Flutter 三方库 superclass 的鸿蒙化适配指南 - 支持原生高性能类构造、属性代理与深层元数据解析实战
flutter·harmonyos·鸿蒙·openharmony
Swift社区3 小时前
Flutter 迁移鸿蒙 ArkUI 的真实成本
flutter·华为·harmonyos
牛马11116 小时前
Flutter CustomPainter
flutter
蜡台16 小时前
Flutter 安装配置
android·java·flutter·环境变量
加农炮手Jinx16 小时前
Flutter 组件 ubuntu_service 适配鸿蒙 HarmonyOS 实战:底层系统服务治理,构建鸿蒙 Linux 子系统与守护进程交互架构
flutter·harmonyos·鸿蒙·openharmony·ubuntu_service
里欧跑得慢16 小时前
Flutter 三方库 mobx_codegen — 自动化驱动的高性能响应式状态管理(适配鸿蒙 HarmonyOS Next ohos)
flutter·自动化·harmonyos
王码码203516 小时前
Flutter 三方库 login_client 的鸿蒙化适配指南 - 打造工业级安全登录、OAuth2 自动化鉴权、鸿蒙级身份守门员
flutter·harmonyos·鸿蒙·openharmony·login_client