具有异步订户功能的RxJS Observable

时间:2017-04-05 22:19:08

标签: javascript node.js promise rxjs node-amqp

我正在尝试做一些感觉应该是直截了当的事情,但事实证明非常困难。

我有一个订阅RabbitMQ队列的函数。具体来说,这是Channel.consume函数:http://www.squaremobius.net/amqp.node/channel_api.html#channel_consume

它返回一个使用订阅ID解析的promise - 这是稍后取消订阅所需的 - 并且还有一个回调参数可以在消息从队列中取出时调用。

当我想取消订阅队列时,我需要使用Channel.cancel函数取消使用者:http://www.squaremobius.net/amqp.node/channel_api.html#channel_cancel。这将获取先前返回的订阅ID。

我希望将所有这些内容包装在Observable中,该observable在订阅observable时订阅队列,并在取消订阅observable时取消订阅。然而,由于调用的“双异步”特性,这证明有点困难(我的意思是说它们都有回调并返回一个承诺)。

理想情况下,我希望能够编写的代码是:

return new Rx.Observable(async (subscriber) => {
  var consumeResult = await channel.consume(queueName, (message) => subscriber.next(message));
  return async () => {
    await channel.cancel(consumeResult.consumerTag);
  };
});

但是,这是不可能的,因为此构造函数不支持异步订阅者功能或拆除逻辑。

我无法弄明白这个。我在这里错过了什么吗?为什么这么难?

干杯, 亚历

1 个答案:

答案 0 :(得分:3)

创建的observable不需要等待channel.consume承诺解析,因为观察者(它通过的观察者,而不是订阅者)只能从你提供的功能。

但是,您返回的取消订阅功能必须等待该承诺解决。它可以在内部完成,如下所示:

return new Rx.Observable((observer) => {
  var consumeResult = channel.consume(queueName, (message) => observer.next(message));
  return () => {
    consumeResult.then(() => channel.cancel(consumeResult.consumerTag));
  };
});