rxjs/operators#bufferWhen TypeScript Examples

The following examples show how to use rxjs/operators#bufferWhen. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: api-subscription-from-web-socket.ts    From js-client with MIT License 5 votes vote down vote up
apiSubscriptionFromWebSocket = <MessageReceived, MessageSent>(
	socket: WebSocket,
): APISubscription<MessageReceived, MessageSent> => {
	const _received$ = new Subject<MessageReceived>();
	const _sent$ = new Subject<MessageSent>();
	const _toSend$ = new Subject<MessageSent>();

	const received: Array<MessageReceived> = [];
	const sent: Array<MessageSent> = [];

	_received$.subscribe(receivedMessage => received.push(receivedMessage));
	_sent$.subscribe(sentMessage => sent.push(sentMessage));

	socket.onmessage = message => {
		_received$.next(JSON.parse(message.data.toString()));
	};

	socket.onerror = err => {
		_received$.error(err);
		_sent$.error(err);
	};

	socket.onclose = () => {
		_received$.complete();
		_sent$.complete();
		_toSend$.complete();
	};

	_toSend$
		.pipe(
			// If the socket is still connecting, buffer until the socket is open. Once open, send the buffer through.
			// If the socket is already open, buffer until _toSend$ emits. Since _toSend$ is the source, each buffer contains exactly one item.
			bufferWhen(() => iif(() => getWebSocketState(socket) === 'connecting', fromEvent(socket, 'open'), _toSend$)),

			// Flatten the arrays of messages, so that the Observer gets one message at a time
			concatMap(messages => from(messages)),
		)
		.subscribe(message => {
			if (getWebSocketState(socket) !== 'open') {
				return;
			}

			if (message === undefined) {
				return;
			}
			const stringMessage = typeof message === 'string' ? message : JSON.stringify(message);
			socket.send(stringMessage);
			_sent$.next(message);
		});

	return {
		send: async message => void _toSend$.next(message),
		close: () => socket.close(),
		received,
		received$: _received$.asObservable(),
		sent,
		sent$: _sent$.asObservable(),
	};
}