在StateNotifier子类中使用AsyncValue.guard而不是try/catch的方法

538 阅读1分钟

在编写你自己的StateNotifier 子类时,使用try/catch块来处理可能失败的Futures是很常见的。

class SignOutButtonController extends StateNotifier<AsyncValue> {
  SignOutButtonController({required this.authRepository})
      : super(const AsyncValue.data(null));
  final AuthRepository authRepository;

  Future<void> signOut() async {
    try {
      state = const AsyncValue.loading();
      await authRepository.signOut(); // this future can fail
      state = const AsyncValue.data(null);
    } catch (e) {
      state = AsyncValue.error(e);
    }
  }
}

在这种情况下,AsyncValue.guard 是一个方便的选择,它为我们完成了所有的重任。

Future<void> signOut() async {
  state = const AsyncValue.loading();
  state = await AsyncValue.guard(() => authRepository.signOut());
}

下面是这个方法在AsyncValue 类中的实现方式。

abstract class AsyncValue<T> {
  static Future<AsyncValue<T>> guard<T>(Future<T> Function() future) async {
    try {
      return AsyncValue.data(await future());
    } catch (err, stack) {
      return AsyncValue.error(err, stackTrace: stack);
    }
  }
}

在这里了解更多。AsyncValue.guard()方法

编码愉快!

Riverpod提示。你

可以在你的StateNotifier子类里面用AsyncValue.guard()代替繁琐的try/catch块。pic.twitter.com/Q89nOrNrJD-

Andrea Bizzotto 💙 (@biz84)April 19, 2022