我正在尝试学习riverpod,我想知道如果另一个FutureProvider的数据已经可用,是否有可能“跳过”AsyncLoading。下面是一个简单的例子,说明我正在尝试做什么:
@Riverpod(keepAlive: true)
Future<Map<String, MyObject>> fetchDataMap(FetchDataMapRef ref) {
// Fetch data from the network
return data;
}
@riverpod
FutureOr<List<MyObject>> dataList(DataListRef ref, List<String> ids) {
final dataMap = await ref.watch(fetchDataMapProvider.future);
return ids
.map((id) => dataMap[id])
.whereType<MyObject>()
.toList();
}
第一次读取/查看提供程序时,预计会发出一个AsyncLoading对象,但几乎所有后续调用都将具有AsyncData,但即使是这种情况,当我查看新的dataListProvider时,它将返回AsyncLoading,而不管fetchDataMapProvider的当前状态如何。
有没有办法跳过这个加载?
我尝试用FutureOr替换Future,并在等待之前读取当前状态,但AsyncLoading仍然是第一个发出的状态。
@riverpod
FutureOr<List<MyObject>> dataList(
DataListRef ref,
List<String> ids,
) async {
final future = ref.watch(fetchDataMapProvider.future);
final currentAsyncValue = ref.read(fetchDataMapProvider);
final dataMap = currentAsyncValue.valueOrNull ?? await future;
return ids
.map((id) => dataMap[id])
.whereType<MyObject>()
.toList();
}
我还尝试了以下内容:
@riverpod
AsyncData<List<MyObject>> dataList(
DataListRef ref,
List<String> ids,
) async {
final currentAsyncValue = ref.watch(fetchDataMapProvider);
return currentAsyncValue.when(
data: (data) => ids
.map((id) => dataMap[id])
.whereType<MyObject>()
.toList(),
error: (error, stackTrace) => AsyncError(error, stackTrace),
loading () => AsyncLoading(),
);
}
但它看起来非常笨拙,我会失去对dataListProvider.future的支持。
1条答案
按热度按时间rslzwgfq1#
回答我自己的问题:未来就是答案!
经过一些尝试和错误,我已经找到了解决问题的方法,因为我使用的是异步函数,它总是返回一个Future,而riverpod将不得不等待它,即使它已经有一个值。要解决这个问题,我需要做的就是删除async并返回一个future: