RxJS - Return 具有价值的主题
RxJS - Return subject with value
我创建了一个身份验证服务,组件可以订阅权限更改(login/logout/role 更改等)。
在 isAuthenticated 函数中,我正在 returning 一个主题。
问题是我想 return 带有值的主题(比如 Observable.of。现在,我正在使用 setTimeout。
@Injectable()
export class AuthenticationService {
constructor(private credentials: CredantialsStorageService,
private oauthService:OAuth2Service,
private secureHttp: SecureHttpService) {}
private isAuthenticatedSubject: Subject<boolean> = new Subject<boolean>();
login(email:string, password: string, remember?:boolean ): Observable<boolean> {
return this.oauthService.login(email, password)
.flatMap(() => this.getAndStoreUserCredantials())
.map((userCredantials: any) => {
this.isAuthenticatedSubject.next(true);
return true;
})
}
logout(): Observable<void> {
return this.secureHttp.post('/logout', null)
.finally(() => {
this.credentials.clear();
this.oauthService.clear();
this.isAuthenticatedSubject.next(false);
})
.map(() => null);
}
isAuthenticated(): Observable<boolean> {
setTimeout(() => { //Hack - find a way to change this
this.isAuthenticatedSubject.next(this.oauthService.isAuthenticated());
})
return this.isAuthenticatedSubject;
}
private getAndStoreUserCredantials() {
return this.secureHttp.get('/user/info')
.map((res:Response) => {
let userCredantials = res.json();
this.credentials.set(userCredantials);
return userCredantials;
})
}
}
您可以 return 它作为 Observable 使用 .asObservable()
。
isAuthenticated(): Observable<boolean> {
setTimeout(() => { //Hack - find a way to change this
this.isAuthenticatedSubject.next(this.oauthService.isAuthenticated());
})
return this.isAuthenticatedSubject.asObservable();
}
编辑:
但是,如果你想在你的方法中添加一些延迟,你可以使用 Obersvable.delay()
,然后使用 .do()
运算符:
isAuthenticated(): Observable<boolean> {
Observable
.delay(1000) //delay for 1000ms
.do(() => {
this.isAuthenticatedSubject.next(this.oauthService.isAuthenticated());
});
return this.isAuthenticatedSubject.asObservable();
}
如果您想为 Subject
设置初始值,您可以使用 BehaviorSubject
。唯一的区别是您将初始值传递给 BehaviorSubject
构造函数。
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
const subject = new BehaviorSubject(42);
subject.subscribe((value) => console.log(value));
// 42
subject.next(84);
// 84
我认为最简单的方法是使用 startWith()
运算符:
isAuthenticated(): Observable<boolean> {
return this.isAuthenticatedSubject.startWith(this.oauthService.isAuthenticated());
}
您也可以使用 BehaviorSubject
或 ReplaySubject
,但它们只会重复已经通过它们的值。也许还可以查看此答案以获取更详细的描述有什么区别:.
我创建了一个身份验证服务,组件可以订阅权限更改(login/logout/role 更改等)。 在 isAuthenticated 函数中,我正在 returning 一个主题。 问题是我想 return 带有值的主题(比如 Observable.of。现在,我正在使用 setTimeout。
@Injectable()
export class AuthenticationService {
constructor(private credentials: CredantialsStorageService,
private oauthService:OAuth2Service,
private secureHttp: SecureHttpService) {}
private isAuthenticatedSubject: Subject<boolean> = new Subject<boolean>();
login(email:string, password: string, remember?:boolean ): Observable<boolean> {
return this.oauthService.login(email, password)
.flatMap(() => this.getAndStoreUserCredantials())
.map((userCredantials: any) => {
this.isAuthenticatedSubject.next(true);
return true;
})
}
logout(): Observable<void> {
return this.secureHttp.post('/logout', null)
.finally(() => {
this.credentials.clear();
this.oauthService.clear();
this.isAuthenticatedSubject.next(false);
})
.map(() => null);
}
isAuthenticated(): Observable<boolean> {
setTimeout(() => { //Hack - find a way to change this
this.isAuthenticatedSubject.next(this.oauthService.isAuthenticated());
})
return this.isAuthenticatedSubject;
}
private getAndStoreUserCredantials() {
return this.secureHttp.get('/user/info')
.map((res:Response) => {
let userCredantials = res.json();
this.credentials.set(userCredantials);
return userCredantials;
})
}
}
您可以 return 它作为 Observable 使用 .asObservable()
。
isAuthenticated(): Observable<boolean> {
setTimeout(() => { //Hack - find a way to change this
this.isAuthenticatedSubject.next(this.oauthService.isAuthenticated());
})
return this.isAuthenticatedSubject.asObservable();
}
编辑:
但是,如果你想在你的方法中添加一些延迟,你可以使用 Obersvable.delay()
,然后使用 .do()
运算符:
isAuthenticated(): Observable<boolean> {
Observable
.delay(1000) //delay for 1000ms
.do(() => {
this.isAuthenticatedSubject.next(this.oauthService.isAuthenticated());
});
return this.isAuthenticatedSubject.asObservable();
}
如果您想为 Subject
设置初始值,您可以使用 BehaviorSubject
。唯一的区别是您将初始值传递给 BehaviorSubject
构造函数。
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
const subject = new BehaviorSubject(42);
subject.subscribe((value) => console.log(value));
// 42
subject.next(84);
// 84
我认为最简单的方法是使用 startWith()
运算符:
isAuthenticated(): Observable<boolean> {
return this.isAuthenticatedSubject.startWith(this.oauthService.isAuthenticated());
}
您也可以使用 BehaviorSubject
或 ReplaySubject
,但它们只会重复已经通过它们的值。也许还可以查看此答案以获取更详细的描述有什么区别: