javascript - Rxjs - 在等待方法执行时阻止后续请求
问题描述
我有一个类,UserPermissionsService
它在最初被访问时发出一个服务器请求。请求完成后,后续调用将使用存储在 a 中的数据BehaviorSubject
来完成其操作。但是,如果多个同时发生,该init
方法将不会完成,并且会发生多个服务器请求。
如何重构以下类以强制后续调用init
在执行之前等待初始请求完成?
@Injectable({
providedIn: 'root'
})
export class UserPermissionsService implements OnDestroy{
private _permissions = new BehaviorSubject<AppliedPermissions>(null);
public permissionSnapshot: AppliedPermissions;
public permissions: Observable<AppliedPermissions> = this._permissions.asObservable();
constructor(private _userService: UserService) {
}
init(): Observable<AppliedPermissions> {
return this._userService.getPermissions()
.pipe(tap(p => {
this._permissions.next(p)
this.permissionSnapshot = p;
}));
}
hasPermission(permission: string): Observable<boolean> {
return this._permissions.pipe(
switchMap(value => value ? of(value) : this.init()),
map(response => {
const perm = response.permissions
.find(el => el.permissionName === permission);
if (!perm)
return false;
return perm.allow;
}),
catchError(_ => of(false))
);
}
inRole(role: string): Observable<boolean> {
return this._permissions.pipe(
switchMap(value => value ? of(value) : this.init()),
map(response => {
return !!response.roles.find(el => el === role);
}),
catchError(_ => of(false))
);
}
ngOnDestroy(): void {
this._permissions?.complete();
}
}
解决方案
你考虑过OnInit()
export class App implements OnInit {
constructor() {
// Called first time before the ngOnInit()
}
ngOnInit() {
// Called after the constructor and called after the first ngOnChanges()
}
}
现在回答您的问题 - 尝试flatmap
保留/控制顺序,这样可以确保保留执行顺序。例如看这里
first
.flatMap(() => second)
.flatMap(() => third)
.subscribe(()=> console.log('finished'));
另外的选择
// use this wrapper
function WaitForComplete<T>(signal: Observable<any>) {
return (sourceInit: Observable<T>) => signal.pipe(
first(), switchMap(_ => sourceInit),
);
}
// force the waiting to complete, by deferring the subscribe on the first source
// till the signal observable completes/emits (many versions of this out there)
var YourSecond =
anotherObservable.pipe(WaitForComplete(YourFirstObservableFunction), take(1));
更新:服务可以实现ngOnInit()
推荐阅读
- ios - 检查用户名是否唯一抛出错误:void 函数中的意外非 void 返回类型
- javascript - 如何使用javascript检查输入是否包含特殊字符
- highcharts - 如何删除我在折线图中添加的条形图上的数字数据图?
- python-3.x - 仅针对给定坐标计算矩阵乘法
- ffmpeg - 同步 RTSP 音频和视频
- python - 如何在 RidgeCV 模型上应用 GridSearch
- c# - Lambda 在 Console.Writeline(s) 和 Log,Info(s) 之间切换
- firebase - 在 travis 中设置环境变量
- java - 数据 Jpa 测试无法加载属性
- python - django 中的“python manage.py migrate”到底是做什么的?