在StreamProvider回调中计算一个FutureProvider



我有一个流提供程序,它依赖于一个请求来解析。然而,执行步骤放在第一个await语句上,导致响应为空。会抛出错误

请求提供者

final postProvider = FutureProvider.family.autoDispose(
(ref, Tuple2<String?, Map<dynamic, dynamic>?> info) async {
var path = info.item1 ?? '';
var payload = info.item2;
final url = backendUrl().replace(path: path);
return await http.post(
url,
headers: {
'X-FIREBASE_TOKEN':
await ref.read(authProvider).currentUser!.getIdToken() //this is where execution steps out
},
body: payload != null ? jsonEncode(payload) : null,
);
},
);

StreamProvider:

final chatProvider = StreamProvider.autoDispose((ref) {
final chatId = ref.watch(chatIdProvider);
if (chatId == null) {
final resp = ref
.watch(postProvider(const Tuple2('create-chat', null)))
.value!; //this evaluates to null.
ref.read(chatIdProvider.notifier).state = jsonDecode(resp.body)['chat_id'];
}
final uid = ref.watch(userStreamProvider).value!.uid;
return ref.read(docRefProvider('${uid}_chats/$chatId')).snapshots();
});

我不能从FutureProvider中使用future,因为这需要我有一个async回调,它不会返回future而不是Stream。我该如何解决这个问题?

您可以尝试使用yield,就像下面的示例一样。if块检查chatId是否为null,如果是,它等待postProvider通过使用await ref.watch(postProvider(const Tuple2('create-chat', null)).last)来解析。

final chatProvider = StreamProvider.autoDispose((ref) async* {
final chatId = ref.watch(chatIdProvider);
if (chatId == null) {
final resp = await ref.watch(postProvider(const Tuple2('create-chat', null)).last);
ref.read(chatIdProvider.notifier).state = jsonDecode(resp.body)['chat_id'];
}
final uid = ref.watch(userStreamProvider).value!.uid;
yield* ref.read(docRefProvider('${uid}_chats/$chatId')).snapshots();
});

更多关于这里https://dart.dev/language/functions#generators这里https://stackoverflow.com/a/56173833/5666202

resp上的last返回一个Future,该Future返回从提供程序发出的最后一个值,这似乎是您在这种情况下所需要的