我试图调整我为会话超时创建的一些代码。 每当用户与该功能交互时,我想重置计时器以再次开始倒计时。我在解决如何向此example
注入类似代码时遇到了困难C#代码 - 我试图整合:
var update = new Subject<bool>();
var res =
update
.Select(x => Observable.Interval(TimeSpan.FromSeconds(10.0)))
.Switch();
res
.Subscribe(_ => Console.WriteLine("Status sent."));
update.OnNext(true);
res
.Subscribe(_ =>
{
update.OnNext(true);
Console.WriteLine("Status sent.");
});
据我所知,RxJS库的C#风格和我的变量名映射的Typescript RxJS等价物是:
C#/example Typescript/mine
update resetManager
.Select .map
(来自here - (参见标题标题))
.OnNext .next
.Interval .timer
我以为我可以插入一个do并链接resetManager - 但由于一个是布尔值而另一个是AuthState,我似乎遇到了困难。
我想知道RxJS大师是否可以提供建议。欢呼声。
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';
import 'rxjs/add/Observable/timer';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/switch';
@Injectable()
export class AuthService {
private authState: AuthState;
private authManager: BehaviorSubject<AuthState>;
public authChange$: Observable<AuthState>;
private resetManager: Subject<boolean>;
constructor() {
this.authManager = new BehaviorSubject(AuthState.LOGGED_OUT);
this.authChange$ = this.authManager.asObservable();
this.authChange$
.filter((authState:AuthState) => authState === AuthState.LOGGED_IN)
.map( (authState:AuthState) => Observable.timer(SESSION_TIMEOUT))
.do( () =>
console.log('Logged In. Session Timout counting down from now'))
.switch()
.subscribe( () => {console.log('Timer ended: Logging out')
this.logout();
});
}
login() {
this.setAuthState(AuthState.LOGGED_IN);
}
logout() {
this.setAuthState(AuthState.LOGGED_OUT);
}
resetSessionTimer() {
this.resetManager.next(true);
}
emitAuthState():void {
this.authManager.next(this.authState);
}
private setAuthState(newAuthState:AuthState):void {
console.log('AuthService: setAuthState: ',
AuthState[newAuthState.toString()]);
if (newAuthState != this.authState) {
this.authState = newAuthState;
this.emitAuthState();
}
}
export enum AuthState {
LOGGED_IN,
LOGGED_OUT
}
const SESSION_TIMEOUT = 5000;
答案 0 :(得分:0)
我终于知道如何做到这一点......
import { Events } from 'ionic-angular';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/mapTo';
import 'rxjs/add/observable/defer';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/merge';
import 'rxjs/add/operator/scan';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/switchMap';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
export enum AuthState {
LOGGED_IN,
LOGGED_OUT
}
const SESSION_TIMEOUT = 10; // seconds
export class AuthService {
private timer: number;
private tick$: Observable<number>;
private countDown$: Observable<number>;
private subscriptions:Subscription[];
constructor(
private events:Events
) {
this.tick$ =Observable.interval(1000).mapTo(-1);
this.countDown$ = Observable
.defer(() => Observable.of(this.timer))
.merge(this.tick$)
.scan((acc,curr) => acc + curr)
this.events.subscribe(RESET_COUNTDOWN, (action:string) => {
this.resetSessionTimer(action);
});
}
beginCountDown() {
let sub:Subscription;
while (this.subscriptions.length > 0) {
sub = this.subscriptions.pop();
sub.unsubscribe();
};
this.timer = SESSION_TIMEOUT;
sub = this.countDown$
.filter(timer => timer >= 0)
.subscribe(timer =>
{this.timer = timer;
if (this.timer === 1) {
this.logout();
}
console.log(this.timer);
});
this.subscriptions.push(sub);
}
resetSessionTimer(action:string) {
console.log('AuthService: resetSessionTimer(): ' + action);
this.beginCountDown();
}
emitAuthState():void {
this.authManager.next(this.authState);
}
private setAuthState(newAuthState:AuthState):void {
if (newAuthState != this.authState) {
this.authState = newAuthState;
this.emitAuthState();
}
}
login(
clickStream$: BehaviorSubject<any>
) {
this.response$ = clickStream$.switchMap(click => {
return this.webServiceUtil.testLogin();
}
);
this.response$.subscribe((response:Response) => {
this.setAuthState(AuthState.LOGGED_IN);
},
(err:any) => {
this.setAuthState(AuthState.LOGGED_OUT);
})
}
logout() {
if (this.authState === AuthState.LOGGED_IN) {
this.setAuthState(AuthState.LOGGED_OUT);
}
}
}
RESET_COUNTDOWN事件可能会因更改页面或执行HTTP请求而触发。这将迫使倒计时再次开始,同时只有一个订阅,因此跟踪一系列订阅..你在重置时立即取消。