rxjs首先完成了整个流链

rxjs首先完成了整个流链,rxjs,json-rpc,Rxjs,Json Rpc,我有一个angular 5应用程序,rxjs WebsocketSubject发送jsonrpc消息 这是我的sendRequest函数 sendRequest(request: Request): Promise<Response> { console.log(request); this.socket.next(JSON.stringify(request)); return this.onResponse().filter((response: Respons

我有一个angular 5应用程序,rxjs WebsocketSubject发送jsonrpc消息

这是我的sendRequest函数

sendRequest(request: Request): Promise<Response> {

  console.log(request);

  this.socket.next(JSON.stringify(request));

  return this.onResponse().filter((response: Response) => {
    return response.id === request.id;
  }).first().toPromise().then((response) => {

    console.log(response);

    if (response.error) {
      console.log('error');
      throw new RpcError(response.error);
    }

    return response;

  });

}
我需要找到一种方法,以某种方式将我的过滤器与原始流分离。

这是可行的。 关键是将消息处理与底层websocketSubject分离

import {Injectable} from "@angular/core";
import {WebSocketSubject, WebSocketSubjectConfig} from "rxjs/observable/dom/WebSocketSubject";
import {MessageFactory, Notification, Request, Response, RpcError} from "../misc/jsonrpc";
import {ReplaySubject} from "rxjs/ReplaySubject";
import {Observable} from "rxjs/Observable";
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/first';
import 'rxjs/add/observable/from';
import {Subject} from "rxjs/Subject";

export enum ConnectionState {
  CONNECTED = "Connected",
  CONNECTING = "Connecting",
  CLOSING = "Closing",
  DISCONNECTED = "Disconnected"
}

@Injectable()
export class WebsocketService {

  private connectionState = new ReplaySubject<ConnectionState>(1);
  private socket: WebSocketSubject<ArrayBuffer | Object>;
  private config: WebSocketSubjectConfig;

  private messageObserver = new Subject<MessageFactory>();
  private binaryObserver = new Subject<ArrayBuffer>();

  constructor() {

    const protocol = location.protocol === 'https' ? 'wss' : 'ws';
    const host = location.hostname;
    const port = 3000; // location.port;

    this.config = {
      binaryType: "arraybuffer",
      url: `${protocol}://${host}:${port}`,
      openObserver: {
        next: () => this.connectionState.next(ConnectionState.CONNECTED)
      },
      closingObserver: {
        next: () => this.connectionState.next(ConnectionState.CLOSING)
      },
      closeObserver: {
        next: () => this.connectionState.next(ConnectionState.DISCONNECTED)
      },
      resultSelector: (e: MessageEvent) => {

        try {

          if (e.data instanceof ArrayBuffer) {
            return e.data;
          } else {
            return JSON.parse(e.data);
          }

        } catch (e) {

          console.error(e);
          return null;

        }

      }
    };

    this.connectionState.next(ConnectionState.CONNECTING);
    this.socket = new WebSocketSubject(this.config);

    this.socket.filter((message: any) => {
      return message instanceof ArrayBuffer;
    }).subscribe((message: ArrayBuffer) => {
      this.binaryObserver.next(message);
    });

    this.socket.filter((message: any) => {
      return !(message instanceof ArrayBuffer);
    }).subscribe((message: ArrayBuffer) => {
      this.messageObserver.next(MessageFactory.from(message));
    });

    this.connectionState.subscribe((state) => {
      console.log(`WS state ${state}`);
    });

  }

  onResponse(): Observable<Response> {
    return this.messageObserver.filter((message: MessageFactory) => {
      return message.isResponse();
    }).map((message: MessageFactory): Response => {
      return message.toResponse();
    });
  }

  sendRequest(request: Request): Promise<Response> {

    console.log(request);

    this.socket.next(JSON.stringify(request));

    return this.onResponse().filter((response: Response) => {
      return request.id === response.id;
    }).first().toPromise().then((response) => {

      console.log(response);

      if (response.error) {
        console.log('error');
        throw new RpcError(response.error);
      }

      return response;

    });

  }

  sendNotification(notification: Notification): void {
    this.socket.next(JSON.stringify(notification));
  }

}

为什么你甚至需要先使用.toPromise.then?像这样订阅不是更容易吗?onResponse.filter…subscribe。。。;?是的,但我的理解可能是我错了,我必须清理订阅,我期待一个单一的结果。因此,使用承诺应该是好的。但是,toPromise只能在观察到的情况下解决问题。完成后,您现在的操作方式有什么问题?首先完成整个流程。因此,我的websocketSubject已完成,因为onResponse从我的websocketSubject返回一个经过过滤的可观察项。因此,我的websocket在每次Resonse后都会关闭。完成此链不会完成此.onResponse或其他内容中的主题。从您在编辑中显示的内容来看,问题将出现在其他地方,而不是完成RxJS链。
import {Injectable} from "@angular/core";
import {WebSocketSubject, WebSocketSubjectConfig} from "rxjs/observable/dom/WebSocketSubject";
import {MessageFactory, Notification, Request, Response, RpcError} from "../misc/jsonrpc";
import {ReplaySubject} from "rxjs/ReplaySubject";
import {Observable} from "rxjs/Observable";
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/first';
import 'rxjs/add/observable/from';

export enum ConnectionState {
  CONNECTED = "Connected",
  CONNECTING = "Connecting",
  CLOSING = "Closing",
  DISCONNECTED = "Disconnected"
}

@Injectable()
export class WebsocketService {

  private connectionState = new ReplaySubject<ConnectionState>(1);
  private socket: WebSocketSubject<ArrayBuffer | Object>;
  private config: WebSocketSubjectConfig;

  constructor() {

    console.log('ctor');

    const protocol = location.protocol === 'https' ? 'wss' : 'ws';
    const host = location.hostname;
    const port = 3000; // location.port;

    this.config = {
      binaryType: "arraybuffer",
      url: `${protocol}://${host}:${port}`,
      openObserver: {
        next: () => this.connectionState.next(ConnectionState.CONNECTED)
      },
      closingObserver: {
        next: () => this.connectionState.next(ConnectionState.CLOSING)
      },
      closeObserver: {
        next: () => this.connectionState.next(ConnectionState.DISCONNECTED)
      },
      resultSelector: (e: MessageEvent) => {

        try {

          if (e.data instanceof ArrayBuffer) {
            return e.data;
          } else {
            return JSON.parse(e.data);
          }

        } catch (e) {

          console.error(e);
          return null;

        }

      }
    };

    this.connectionState.next(ConnectionState.CONNECTING);
    this.socket = new WebSocketSubject(this.config);

    this.connectionState.subscribe((state) => {
      console.log(`WS state ${state}`);
    });

  }

  onBinaryData(): Observable<ArrayBuffer> {
    return this.socket.filter((message: any) => {
      return message instanceof ArrayBuffer;
    });
  }

  onMessageData(): Observable<Object> {
    return this.socket.filter((message: any) => {
      return !(message instanceof ArrayBuffer);
    });
  }

  onResponse(): Observable<Response> {
    return this.onMessageData().filter((message) => {
      return MessageFactory.from(message).isResponse();
    }).map((message): Response => {
      return MessageFactory.from(message).toResponse();
    });
  }

  sendRequest(request: Request): Promise<Response> {

    console.log(request);

    this.socket.next(JSON.stringify(request));

    return new Promise<Response>((resolve, reject) => {

      const responseSubscription = this.onResponse().filter((response: Response) => {
        console.log('filter');
        return response.id === request.id;
      }).subscribe((response: Response) => {

        responseSubscription.unsubscribe();
        resolve(response);

      });

    });

  }

  sendNotification(notification: Notification): void {
    this.socket.next(JSON.stringify(notification));
  }

}
Using Angular 5.0.2
websocket.service.ts:27 ctor
websocket.service.ts:69 WS state Connecting
core.js:3565 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
websocket.service.ts:96 Request {jsonrpc: "2.0", id: "b042005c-5fbf-5ffc-fbd1-df68fae5882e", method: "appointment_list_get", params: undefined}
websocket.service.ts:69 WS state Connected
websocket.service.ts:103 filter
websocket.service.ts:69 WS state Disconnected
import {Injectable} from "@angular/core";
import {WebSocketSubject, WebSocketSubjectConfig} from "rxjs/observable/dom/WebSocketSubject";
import {MessageFactory, Notification, Request, Response, RpcError} from "../misc/jsonrpc";
import {ReplaySubject} from "rxjs/ReplaySubject";
import {Observable} from "rxjs/Observable";
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/first';
import 'rxjs/add/observable/from';
import {Subject} from "rxjs/Subject";

export enum ConnectionState {
  CONNECTED = "Connected",
  CONNECTING = "Connecting",
  CLOSING = "Closing",
  DISCONNECTED = "Disconnected"
}

@Injectable()
export class WebsocketService {

  private connectionState = new ReplaySubject<ConnectionState>(1);
  private socket: WebSocketSubject<ArrayBuffer | Object>;
  private config: WebSocketSubjectConfig;

  private messageObserver = new Subject<MessageFactory>();
  private binaryObserver = new Subject<ArrayBuffer>();

  constructor() {

    const protocol = location.protocol === 'https' ? 'wss' : 'ws';
    const host = location.hostname;
    const port = 3000; // location.port;

    this.config = {
      binaryType: "arraybuffer",
      url: `${protocol}://${host}:${port}`,
      openObserver: {
        next: () => this.connectionState.next(ConnectionState.CONNECTED)
      },
      closingObserver: {
        next: () => this.connectionState.next(ConnectionState.CLOSING)
      },
      closeObserver: {
        next: () => this.connectionState.next(ConnectionState.DISCONNECTED)
      },
      resultSelector: (e: MessageEvent) => {

        try {

          if (e.data instanceof ArrayBuffer) {
            return e.data;
          } else {
            return JSON.parse(e.data);
          }

        } catch (e) {

          console.error(e);
          return null;

        }

      }
    };

    this.connectionState.next(ConnectionState.CONNECTING);
    this.socket = new WebSocketSubject(this.config);

    this.socket.filter((message: any) => {
      return message instanceof ArrayBuffer;
    }).subscribe((message: ArrayBuffer) => {
      this.binaryObserver.next(message);
    });

    this.socket.filter((message: any) => {
      return !(message instanceof ArrayBuffer);
    }).subscribe((message: ArrayBuffer) => {
      this.messageObserver.next(MessageFactory.from(message));
    });

    this.connectionState.subscribe((state) => {
      console.log(`WS state ${state}`);
    });

  }

  onResponse(): Observable<Response> {
    return this.messageObserver.filter((message: MessageFactory) => {
      return message.isResponse();
    }).map((message: MessageFactory): Response => {
      return message.toResponse();
    });
  }

  sendRequest(request: Request): Promise<Response> {

    console.log(request);

    this.socket.next(JSON.stringify(request));

    return this.onResponse().filter((response: Response) => {
      return request.id === response.id;
    }).first().toPromise().then((response) => {

      console.log(response);

      if (response.error) {
        console.log('error');
        throw new RpcError(response.error);
      }

      return response;

    });

  }

  sendNotification(notification: Notification): void {
    this.socket.next(JSON.stringify(notification));
  }

}