发射一次,然后每秒发射一次,直到值改变

时间:2018-12-31 06:04:29

标签: rxjs rxjs6

我正在工作。收到套接字消息后,将立即发出一个值,此后每秒发出一个值(增加使用期限),直到再次收到套接字为止。

但是,无论是否接收到套接字,我都希望它每秒发出一次。因此它将开始每秒钟发射一次,但是当套接字接收到该属性时,它们将更改为新的属性,并且每秒都会发射一次。

不太清楚该怎么办。

updated: Observable<TargetDevice>;

this.updated = socketService.onMessage.pipe(
  filter(
    message =>
      message.messageType === SocketIoMessageType.Device &&
      message.data.id === this.id
  ),
  map((message: SocketIoMessage) => <Device>message.data),
  tap(d => this.setProps(d)),
  switchMap(d =>
    timer(0, 1000).pipe(
      tap(tick => (this.age = d.age + tick)),
      map(() => this)
    )
  )
);

3 个答案:

答案 0 :(得分:1)

您希望使用combineLateststartWith来实现所需的行为:

combineLatest(
    socketService.onMessage.pipe(
        startWith(DEFAULT_MESSAGE)
    ),
    timer(0, 1000)
).pipe(
    //...
)

答案 1 :(得分:0)

我认为您想要这样的东西。 您使用switchMap是正确的。有趣的是,在发出下一个值之后,它确实取消了可观察到的源订阅。

socketService.onMessage.pipe(
    switchMap(value => interval(1000).map(() => value))
);

在RxJs游乐场here中查看

答案 2 :(得分:0)

针对您的问题的可能解决方案之一是创建beforeSocketMessage$流,并使用takeUntil运算符对其进行限制。

const beforeSocketMessage$ = interval(1000).pipe(mapTo('beforeSocketMessage'), takeUntil(socketService.onMessage));


const message$ = socketService.onMessage.pipe(
    filter(/* you filter*/),
    map((message: SocketIoMessage) => <Device>message.data),
    tap(d => this.setProps(d)),
    switchMap((data) => interval(0, 1000).pipe(mapTo(data))),
    tap(tick => (this.age = d.age + tick)),
    mapTo(this)
)

this.update = merge(beforeSocketMessage$, message$);

stackblitz.com上的简化版本:https://stackblitz.com/edit/rxjs-jwg2cb?devtoolsheight=60