我订阅了每n秒发生一次事件的计时器
Observable.interval(1000)
.startWith(0)
.map( x => { return 'USER'; }
我还有其他可观察的结果,它产生的结果是从开始时无法获得的,需要一些时间才能解决。超时事件累积,当另一个事件最终触发时,我有大量请求。
.zip(tokenService.token, (privilege: string, token: Token) => {
/*get request body*/ }
.flatMap((body: any) => { /* perform refresh request */ }
.map( x => { return x.json(); })
.subscribe( json => {
let token = json['token']'
tokenService.setToken(token);
});
有没有办法只保留一个来自计时器的最后一个事件,并丢弃其余的事件?
.last()
对我不起作用,因为它确实只返回一个事件,但它什么也没有返回,我没有看到下一个超时事件。
也许这对我的问题不是一个好角度?我想每隔n秒刷新一次令牌,只有当我手上有有效令牌时才这样做(现在服务提供Observable<Token>
)
编辑:好的,我发现这被称为背压,并且有一篇关于它的文章:https://github.com/ReactiveX/RxJava/wiki/Backpressure
问题仍然存在。
答案 0 :(得分:1)
您基本上希望根据Observable的当前状态重新触发事件。如果令牌有效且已经过了一段时间,则应创建新令牌,否则不会发生任何事情。
请参阅以下example on jsbin,其中提供了一些如何完成此操作的示例代码。使用按钮创建新的有效令牌。从那时起每秒都会生成一个新令牌(有效期为五秒)。通过无效按钮使令牌无效后,新令牌的生成将停止。
function createToken() {
// Here you would do some (async) things to get a valid token.
return Promise.resolve({ validUntil: new Date(+new Date() + 5000) });
}
function isTokenValid(token) {
const date = new Date();
return token.validUntil > date;
}
// Subject holds copy of latest token.
const token$ = new Rx.ReplaySubject(1);
// Defines the time interval to periodically query new tokens.
const period$ = Rx.Observable.interval(1000);
period$
.withLatestFrom(token$, (p, token) => {
if (isTokenValid(token)) {
createToken()
.then(token => token$.next(token));
}
return token;
})
.filter(token => isTokenValid(token))
.subscribe(x => console.log(x));
// Button stream that invalidates token
const invalidateBtn$ = Rx.Observable.fromEvent(
document.getElementById('invalidateBtn'), 'click')
.subscribe(() => {
token$.next({ validUntil: new Date(0) });
});
// Button stream triggers creation of first valid token
const createBtn$ = Rx.Observable.fromEvent(
document.getElementById('createBtn'), 'click')
.subscribe(() => {
createToken()
.then((token) => token$.next(token));
});