Dart Rx 删除等待
Dart Rx remove await
我正在学习rx/dart。但我很挣扎。有什么方法可以使 属性 同步吗? await currentUser()
迫使我做 属性 async
。但我需要某种技巧,因为我无法更改界面的这一部分。而且我不想使用适配器模式。
属性应该returnStream<User>
。有什么办法可以达到这个目的吗?
Future<Stream<User>> get onUserOrAuthStateChanged async {
return authentication.onAuthStateChanged
.asyncMap<User>((authenticationUser) async {
return await _retrieveUserFromAuthenticationUser(authenticationUser);
}).concatWith([
await currentUser() == null
? Stream.empty()
: userRepository.getStream((await currentUser()).id).skip(1)
]);
}
编辑: 也可以使用 authenticationUser
代替 await currentUser()
。像这样:
Stream<User> get onUserOrAuthStateChanged {
AuthenticationUser currentAuthenticationUser;
return authentication.onAuthStateChanged
.asyncMap<User>((authenticationUser) async {
currentAuthenticationUser = authenticationUser;
return await _retrieveUserFromAuthenticationUser(authenticationUser);
}).concatWith([
currentAuthenticationUser == null
? Stream.empty()
: userRepository.getStream(currentAuthenticationUser.uid).skip(1)
]);
}
通过这种方法,我摆脱了异步,但是在执行 concatWith
方法时 currentAuthenticationUser 总是 null
,因为在 concatWith
currentAuthenticationUser = authenticationUser;
您可以使用 Stream.fromFuture()
将 Future
转换为 Stream
。
这些是一些伪代码选项,因为我不完全了解你的代码,我也没有尝试编译它,只是凭记忆在这里输入。
: userRepository.getStream((Stream.fromFuture(await currentUser())).id).skip(1)
: userRepository.getStream((Stream.fromFuture(currentUser().map((u) => u.id)))).skip(1)
这是我想出的解决方案:
Stream<User> get onUserOrAuthStateChanged {
return authentication.onAuthStateChanged.switchMap((authenticationUser) =>
authenticationUser == null
? Stream.value(null)
: userRepository.getStream(authenticationUser.uid));
}
或者,您可以使用新的 await for
语法代替 RxDart:
Stream<UserProfile> get user$ async* {
await for (final currentUser in _firebaseAuth.onAuthStateChanged) {
if (currentUser != null) {
await for (final user in getUserStreamFromId(currentUser.uid)) {
yield UserProfile.fromFirestore(user);
}
}
}
}
我认为 await for
和 switchMap
一样工作,我创建了一个 gist 来测试它。
如果您需要最新值,可以让 Provider
为您管理缓存。
...
StreamProvider(
create: (context) => userRepo.user$,
),
...
这是 Flutter 的做法。然后很容易在 children:
中访问它
final user = context.watch<UserProfile>();
...
更新
切换可能是个更好的主意,因为飞镖 await for
API 改为绘制排气图:
Stream<UserProfile> get user$ {
return _firebaseAuth.onAuthStateChanged.switchMap((currentUser) async* {
if (currentUser != null) {
await for (final user in getUserStreamFromId(currentUser.uid)) {
yield UserProfile.fromFirestore(user);
}
} else {
yield null;
}
});
}
我正在学习rx/dart。但我很挣扎。有什么方法可以使 属性 同步吗? await currentUser()
迫使我做 属性 async
。但我需要某种技巧,因为我无法更改界面的这一部分。而且我不想使用适配器模式。
属性应该returnStream<User>
。有什么办法可以达到这个目的吗?
Future<Stream<User>> get onUserOrAuthStateChanged async {
return authentication.onAuthStateChanged
.asyncMap<User>((authenticationUser) async {
return await _retrieveUserFromAuthenticationUser(authenticationUser);
}).concatWith([
await currentUser() == null
? Stream.empty()
: userRepository.getStream((await currentUser()).id).skip(1)
]);
}
编辑: 也可以使用 authenticationUser
代替 await currentUser()
。像这样:
Stream<User> get onUserOrAuthStateChanged {
AuthenticationUser currentAuthenticationUser;
return authentication.onAuthStateChanged
.asyncMap<User>((authenticationUser) async {
currentAuthenticationUser = authenticationUser;
return await _retrieveUserFromAuthenticationUser(authenticationUser);
}).concatWith([
currentAuthenticationUser == null
? Stream.empty()
: userRepository.getStream(currentAuthenticationUser.uid).skip(1)
]);
}
通过这种方法,我摆脱了异步,但是在执行 concatWith
方法时 currentAuthenticationUser 总是 null
,因为在 concatWith
currentAuthenticationUser = authenticationUser;
您可以使用 Stream.fromFuture()
将 Future
转换为 Stream
。
这些是一些伪代码选项,因为我不完全了解你的代码,我也没有尝试编译它,只是凭记忆在这里输入。
: userRepository.getStream((Stream.fromFuture(await currentUser())).id).skip(1)
: userRepository.getStream((Stream.fromFuture(currentUser().map((u) => u.id)))).skip(1)
这是我想出的解决方案:
Stream<User> get onUserOrAuthStateChanged {
return authentication.onAuthStateChanged.switchMap((authenticationUser) =>
authenticationUser == null
? Stream.value(null)
: userRepository.getStream(authenticationUser.uid));
}
或者,您可以使用新的 await for
语法代替 RxDart:
Stream<UserProfile> get user$ async* {
await for (final currentUser in _firebaseAuth.onAuthStateChanged) {
if (currentUser != null) {
await for (final user in getUserStreamFromId(currentUser.uid)) {
yield UserProfile.fromFirestore(user);
}
}
}
}
我认为 await for
和 switchMap
一样工作,我创建了一个 gist 来测试它。
如果您需要最新值,可以让 Provider
为您管理缓存。
...
StreamProvider(
create: (context) => userRepo.user$,
),
...
这是 Flutter 的做法。然后很容易在 children:
中访问它final user = context.watch<UserProfile>();
...
更新
切换可能是个更好的主意,因为飞镖 await for
API 改为绘制排气图:
Stream<UserProfile> get user$ {
return _firebaseAuth.onAuthStateChanged.switchMap((currentUser) async* {
if (currentUser != null) {
await for (final user in getUserStreamFromId(currentUser.uid)) {
yield UserProfile.fromFirestore(user);
}
} else {
yield null;
}
});
}