有没有一种在 RxJs 订阅设置后立即执行函数的干净方法?

时间:2021-04-08 19:41:18

标签: javascript events websocket rxjs

我想做什么:

  1. 向 websocket 服务器发送“请求”事件。
  2. 接收与一些附加数据捆绑在一起的即时响应事件。
  3. 随着时间的推移不断收到回复。

我的问题是:

  • 有没有一种更简洁的方式来做我在下面所做的事情?不使用 setTimeout。

首先,看看这个简化的工作示例:

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.log(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>

现在看一个非工作示例。在这里,客户端不会立即得到响应,因为在设置订阅之前发送了 'request' 事件。

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.log(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>

1 个答案:

答案 0 :(得分:2)

您可以使用 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.log(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 不会产生预期的结果在这里,它可以在真正的套接字上正常工作。