flutter 如何在riverpod中跳过使用FutureProvider的AsyncLoading?

sg24os4d  于 2023-06-24  发布在  Flutter
关注(0)|答案(1)|浏览(188)

我正在尝试学习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的支持。

rslzwgfq

rslzwgfq1#

回答我自己的问题:未来就是答案!
经过一些尝试和错误,我已经找到了解决问题的方法,因为我使用的是异步函数,它总是返回一个Future,而riverpod将不得不等待它,即使它已经有一个值。要解决这个问题,我需要做的就是删除async并返回一个future:

@riverpod
FutureOr<List<MyObject>> dataList(
  DataListRef ref,
  List<String> ids,
) {
  final future = ref.watch(fetchDataMapProvider.future);
  final currentAsyncValue = ref.read(fetchDataMapProvider);

  final dataMap = currentAsyncValue.valueOrNull;

  if(dataMap != null){
    return ids
      .map((id) => dataMap[id])
      .whereType<MyObject>()
      .toList();
  }

  return future.map((dataMap) => ids
      .map((id) => dataMap[id])
      .whereType<MyObject>()
      .toList());
}

相关问题