rxjs和SignalR - 等待后台操作的异步通知

时间:2018-03-23 13:28:43

标签: c# angular typescript rxjs asp.net-core-signalr

我正在尝试使用rxjs运算符正确地重写一段代码。 代码的作用是:对webapi控制器执行http调用,该控制器返回一个Guid作为将在服务器上执行的长时间运行后台操作的id。当操作完成后,服务器将通过SignalR向客户端发出此操作已完成的信号,并且客户端代码将恢复(在此之前,它将导致“等待响应”)。

原始摘录如下:

this._service
    .myHttpCall(parameter1)
    .subscribe(
        operationId => {
            let sub = this._notifierHub.onOperationSuccess
                .subscribe(data => {
                    if (operationId !== data.operationId)
                        return;
                    this.notifySuccess();
                    sub.unsubscribe();
                    sub2.unsubscribe();
                });
            let sub2 = this._notifierHub.onOperationFailure
                .subscribe(data => {
                    if (operationId !== data.operationId)
                        return;
                    this.notifyFailure();
                    sub2.unsubscribe();
                    sub.unsubscribe();
                });
        }
    );

this._notifier是一个Angular服务,它将Subject作为Observable公开,并在每次SignalR HubConnection发出时发出。

我想要实现的是将操作Id的管理集成到myHttpCall方法中,这样从调用组件的角度来看,http调用将完成,而不是在返回操作id时,而是在实际操作时通过SignalR标记为完整。

我想写的是:

myHttpCall(parameter1: any) {
    const url = `${this.action("MyHttpCall")}`;
    const body = { parameter1: parameter1 };
    this._http
        .post(url, body, { responseType: "text" })
        .switchMap(operationId => {
            const successObservable = this._notifier
                .onOperationSuccess
                .filter(data => data.operationId === operationId);
            const failureObservable = this._notifier
                .onOperationFailure
                .filter(data => data.operationId === operationId);
            return <what?!>
}

方法体应该是什么,以便我可以从调用者那里写下:

this._service
    .myHttpCall(parameter1)
    .subscribe(
        () => this.notifySuccess(),
        () => this.notifyFailure(),
        () => console.log("HttpCall completed")
    );

1 个答案:

答案 0 :(得分:0)

我认为您可以在switchMap中使用race运算符。

  

使用先发射的observable。

...switchMap(operationId => {
            const successObservable = this._notifier
                .onOperationSuccess
                .filter(data => data.operationId === operationId);
            const failureObservable = this._notifier
                .onOperationFailure
                .filter(data => data.operationId === operationId);

            return race(successObservable, failureObservable);
}