RiverPod - 如何在不在小部件中的 AsyncValue 上等待使用 FutureProvider
Posted
技术标签:
【中文标题】RiverPod - 如何在不在小部件中的 AsyncValue 上等待使用 FutureProvider【英文标题】:RiverPod - How to await using FutureProvider on AsyncValue not in widget 【发布时间】:2021-05-30 08:08:19 【问题描述】:我需要从 Firebase Cloud Firestore 获得 1 个字段 1 次。我如何使用 Widget 构建之外的提供者来实现这一点?
以下是我的综合提供商。 appStartupProvider
是一个 FutureProvider,我想从 firestore 的这个 1 字段中获取 bool
值。但是,appStartupProvider
中的 await 声明“'await' 应用于 'AsyncValue',这不是 'Future'”。
final accountStreamProvider = StreamProvider<Account>((ref)
final database = ref.watch(databaseProvider);
return database != null ? database.accountStream() : const Stream.empty();
);
final _accountSetupCompleteProvider = Provider<AsyncValue<bool>>((ref)
return ref
.watch(accountStreamProvider)
.whenData((account) => account?.accountSetupComplete ?? false);
);
final appStartupProvider = FutureProvider<bool>((ref) async
final accountSetupComplete = await ref.watch(_accountSetupCompleteProvider);
return accountSetupComplete;
);
这里显然缺少一些关于组合提供程序和 AsyncValue 的关键知识,但我正在尝试完成RiverPod Combining Providers 页面上所述的情况,我看到正在使用等待。
【问题讨论】:
你解决了吗?我目前正在学习颤振,并且与 Riverpod 提供商有同样的问题。我想解析提供者的返回值,以便可以在另一个提供者中使用该值,但找不到正确的方法。 @groo 请参阅下面的答案。 ***.com/a/66955043/7259858 【参考方案1】:您发帖时文档中的示例不正确。它已经更新,现在是正确的。
你可以这样写:
final accountStreamProvider = StreamProvider<Account?>((ref)
final database = ref.watch(databaseProvider);
return database != null ? database.accountStream() : const Stream.empty();
);
final _accountSetupCompleteProvider = FutureProvider<bool>((ref) async
final account = await ref.watch(accountStreamProvider.last);
return account?.accountSetupComplete ?? false;
);
final appStartupProvider = FutureProvider<bool>((ref) async
final accountSetupComplete = await ref.watch(_accountSetupCompleteProvider.future);
return accountSetupComplete;
);
或者:
final accountStreamProvider = StreamProvider<Account?>((ref)
final database = ref.watch(databaseProvider);
return database != null ? database.accountStream() : const Stream.empty();
);
final _accountSetupCompleteProvider = Provider<AsyncValue<bool>>((ref)
return ref
.watch(accountStreamProvider)
.whenData((account) => account?.accountSetupComplete ?? false);
);
final appStartupProvider = Provider<bool>((ref)
final accountSetupComplete = ref.watch(_accountSetupCompleteProvider).maybeWhen(
data: (data) => data,
orElse: () => false,
);
return accountSetupComplete;
);
【讨论】:
【参考方案2】:await
的用法可通过以下方式获得:
.future
FutureProvider
documentation
.last
StreamProvider
documentation
例子
final carsListFutureProvider = FutureProvider<List<Car>>((ref)
final backend = ref.watch(backendProvider);
return backend.getList(pathName, (json) => Car.fromJson(json));
);
final carFutureProvider = FutureProvider.family<Car?,int>((ref,id) async
final list = await ref.watch(carsListFutureProvider.future);
return list.firstWhereOrNull((e) => e.id == id);
);
目前文档似乎包含不正确的代码示例。 issue
【讨论】:
以上是关于RiverPod - 如何在不在小部件中的 AsyncValue 上等待使用 FutureProvider的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Riverpod 在没有上下文的情况下设置值
查找已停用小部件的祖先是不安全的 => 使用 Riverpod => 使用 "Navigator.of(context).pushReplacementNamed('/page'
使用 RiverPod 状态管理 Flutter 更改 Text 值