RxJs与套接字io重复的事件

时间:2018-08-12 15:07:28

标签: angular rxjs

我是RxJ的新手,并且想在我的项目中使用这个出色的工具。 我想使用可观察性来管理一个旅行流程,您可以在上面的图片中查看。该流程始于用户请求行程,因此系统将后请求发送到服务器,服务器创建一个带有请求ID的套接字室,以发出有关此请求的所有事件,并返回请求主体和201状态码。 Web应用程序需要开始侦听套接字空间并处理事件。  我使用RxJ进行了一个第一次可以正常运行的实现,请检查:

this.deliveryService.requestObservable.pipe(
  tap((data) => {
    const externalId = data ? data['externalId'] : null;
    if (externalId) {
      this.pendingRequests.push(data as TripRequest);
    }
  }),
  mergeMap((data) => {
    const externalId = data ? data['externalId'] : null;
    if (externalId) {
      return this.deliveryService.listenAcceptedTripRequest(data.externalId);
    } else {
      return Observable.of(null);
    }
  }),
  tap((data) => {
    this.pendingRequests = this.pendingRequests.filter((item) => item.externalId !== data.id);
    this.notificationService.showAcceptedRequestNotification();
  }),
  mergeMap(data => { 
    return this.deliveryService.listenTripStatusNotification(data.id);
  }),
  tap((data) => {
    this.notificationService.showTripStatusNotification(data);
    this.pendingRequests = this.pendingRequests.filter((item) => item.externalId !== data.id);
  })
).subscribe();

我的问题始于第二个用户行程请求,其中第一个可观察对象发出两个事件,在下一个中将发出三个事件,而上述可观察对象将发出越来越多的事件。  我认为这是因为我没有完成任何可观察的任务。  我项目中的第一个可观察对象总是会发出一些事件,但其他可观察对象只需要存在于特定的ID中即可。  可观察的listenAcceptedTripRequest每个ID仅发出一个事件,listenTripStatusNotification Observable可观察的是每个ID包含许多事件,并且某些最终事件(如行程结束和行程被取消)。  那么,实现这种流程的最佳方法是什么? Observable确实是一个不错的选择,或者也许我需要使用其他类型的lib?

Trip flow

1 个答案:

答案 0 :(得分:0)

我通过使用一些过滤器控制套接字事件解决了我的问题。当套接字发出一个事件时,它们不管发出什么内容,因此当我在两个或多个不同的旅行房中收听时,我会遇到错误。  在将事件发布为可观察之前进行了一次验证,我的问题得以解决。我还需要控制可观察的完整状态。

    public listenTripStatusNotification(tripId: string): Observable<any> {
    return Observable.create(observer => {
        this.webSocketService.listen(this.TRIP_STATUS_NOTIFICATION_MESSAGE, tripId, (data) => {
            if(data.tripId === tripId){
                observer.next(data);
                if(this.isFinalStatus(data.status)) {
                    observer.complete();
                }
            }
        })
      });
    }