Что я хочу сделать:
У меня вопрос:
Сначала посмотрите на этот упрощенный рабочий пример:
const { Subject, defer, interval, of} = rxjs;
const EventEmitter = EventEmitter3;
const emitter = new EventEmitter();
const subject = new Subject();
// The next lines mock a websocket server message listener, imagine this being present on server side
emitter.on("request", () => {
subject.next(`Immediate response`);
interval(1000).subscribe((index) =>
subject.next(`Delayed response...${index}`)
);
});
// Imagine the following code being present in the browser
function getData() {
return defer(() => {
// The next line mocks a websocket client sent event
setTimeout(() => emitter.emit("request"), 0);
return subject;
});
}
getData().subscribe((data) => console.info(data));<script src = "https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
<script src = "https://unpkg.com/eventemitter3@latest/umd/eventemitter3.min.js"></script>Теперь посмотрим на нерабочий пример. Здесь клиент не получает немедленного ответа, потому что событие «запрос» отправляется до настройки подписки.
const { Subject, defer, interval, of} = rxjs;
const EventEmitter = EventEmitter3;
const emitter = new EventEmitter();
const subject = new Subject();
// The next lines mock a websocket server message listener, imagine this being present on server side
emitter.on("request", () => {
subject.next(`Immediate response`);
interval(1000).subscribe((index) =>
subject.next(`Delayed response...${index}`)
);
});
// Imagine the following code being present in the browser
function getData() {
return defer(() => {
emitter.emit('request');
return subject;
});
}
getData().subscribe((data) => console.info(data));<script src = "https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
<script src = "https://unpkg.com/eventemitter3@latest/umd/eventemitter3.min.js"></script>


![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете использовать BehaviorSubject вместо Subject:
const { BehaviorSubject, defer, interval, of } = rxjs;
const EventEmitter = EventEmitter3;
const emitter = new EventEmitter();
const subject = new BehaviorSubject();
// The next lines mock a websocket server message listener, imagine this being present on server side
emitter.on("request", () => {
// the timing of this synchronous response would be impossible in a real socket
subject.next(`Immediate response`);
interval(1000).subscribe((index) =>
subject.next(`Delayed response...${index}`)
);
});
// Imagine the following code being present in the browser
function getData() {
return defer(() => {
emitter.emit('request');
return subject;
});
}
getData().subscribe((data) => console.info(data));<script src = "https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
<script src = "https://unpkg.com/eventemitter3@latest/umd/eventemitter3.min.js"></script>Однако имейте в виду, что ответ сервера не может прийти обратно синхронно после отправки запроса сокета таким же образом, как вы реализовали свой макет для этой демонстрации, поэтому, хотя Subject не дает здесь ожидаемого результата, он будет работать нормально. с настоящей розеткой.
Примечание: rxjs предоставляет оболочку webSocket, которая возвращает тему, которую вы можете использовать для отправки (
.next()) и получения (.subscribe()) сообщений.