如果observable在X时间内没有发出值,则会产生副作用

时间:2017-10-25 19:37:34

标签: rxjs

我正在研究一个用例,要求如果一个observable在一定时间内没有发出值,那么我们应该做一些副作用。

提供实际用例:

  • 打开网络套接字连接
  • 如果在X时间内没有发送/接收消息,则关闭Web套接字连接并通知用户

这需要在每个发射值上启动计时器,并在初始订阅observable时启动计时器,然后在指定的时间之后运行某个函数或者直到发出计时器重置的值。我正在努力做到这一点的Rx方式。任何帮助将不胜感激:)

4 个答案:

答案 0 :(得分:5)

debounceTime是您正在寻找的运算符:如果在特定超时内没有其他人跟踪,则它只会发出一个值。收听debounce d流的第一条消息将让您超时并清理您的websocket连接。如果您需要从流的开头开始超时,则可以startWith。具体地:

messages$.startWith(null)
         .debounceTime(timeout)
         .take(1)
         .subscribe(() => { /* side effects */ });

编辑:如果相反,您希望在超时时完全结束消息流(例如,您在onComplete处理程序中清理),只需将debounceTime填入takeUntil

messages$.takeUntil(
  messages$.startWith(null)
           .debounceTime(timeout)
).subscribe(timeout_observer);

使用包含清理onComplete的timeout_observable: Observer<TMessage>

答案 1 :(得分:4)

您可以使用# python 3 In [13]: [f"{title}_{str(i+1)}" for title, i in res.columns] Out[13]: ['KeyWord_1', 'KeyWord_2', 'KeyWord_3', 'date_1', 'date_2', 'date_3'] # python 2 In [14]: [title + "_" + str(i+1) for title, i in res.columns] Out[14]: ['KeyWord_1', 'KeyWord_2', 'KeyWord_3', 'date_1', 'date_2', 'date_3'] In [15]: res.columns = [title + "_" + str(i+1) for title, i in res.columns] In [16]: res Out[16]: KeyWord_1 KeyWord_2 KeyWord_3 date_1 date_2 date_3 Page 1 hello good None mon mon None 2 holy brown crazy tues wed wed

执行此操作
race

如果timer(5000).race(someSource$) .subscribe(notifyUser); 通知速度超过someSource$(5秒),那么timer(5000)&#34;胜出&#34;并继续生活。

如果您只需要someSource$中的一个值,那么someSource$显然可以take(1)first(),这将解决该问题。

我希望有所帮助。

答案 2 :(得分:0)

可能不是一个完美的答案,但它会按照你的要求做,这取决于你想要断开的方式,可能会有一些变化要做

const source = new Rx.Subject();
const duration = 2000;

source.switchMap(value=>{
  return Rx.Observable.of(value).combineLatest(Rx.Observable.timer(2000).mapTo('disconnect').startWith('connected'))
}).flatMap(([emit,timer])=>{
  if(timer=='disconnect'){
    console.log('go disconnect')
  return Rx.Observable.throw('disconnected')
  }
  return Rx.Observable.of(emit)
})
//.catch(e=>Rx.Observable.of('disconnect catch'))
.subscribe(value=>console.log('subscribed->',value),console.log)

setTimeout(() => source.next('normal'), 300);
setTimeout(() => source.next('normal'), 300);
setTimeout(() => source.next('last'), 1800);
setTimeout(() => source.next('ignored'), 4000);
<script src="https://unpkg.com/rxjs@5/bundles/Rx.min.js"></script>

答案 3 :(得分:0)

每个元素上都会启动一个计时器,如果要显示4秒钟,它将超时,您可以在catchError中执行功能

这里有一个例子,它在T0s显示 aa ,然后在t3s显示 bb ,然后在4秒后超时,因为最后一个 cc 要显示10秒

[0]