我正在使用RxJs来听amqp queu(不太相关)。
我有一个函数createConnection
,它返回Observable
,它会发出新的连接对象。一旦建立了连接,我希望每隔 1000ms 发送一次消息,然后在10封消息之后我想关闭连接。
我正在尝试避免外部状态,但如果我不将连接存储在外部变量中,我该如何关闭它?请参阅我从连接开始,然后是flatMap
并推送消息,因此在几个链之后我不再拥有连接对象。
这不是我的流程,但想象一下这样的事情:
createConnection()
.flatMap(connection => connection.createChannel())
.flatMap(channel => channel.send(message))
.do(console.log)
.subscribe(connection => connection.close()) <--- obviously connection isn't here
现在我明白这样做是愚蠢的,但现在我该如何访问连接?我当然可以从var connection = createConnection()
以后以某种方式加入。但是我该怎么做?我甚至不知道如何正确地提出这个问题。 Bottomline,我所拥有的是一个可观察的,发出连接,在连接打开后我想要一个每1000ms发出一次消息的observable(带take(10)
),然后关闭连接
答案 0 :(得分:5)
您问题的直接答案是&#34;您可以通过每个步骤进行操作&#34;。例如,您可以替换此行
.flatMap(connection => connection.createChannel())
这一个:
.flatMap(connection => ({ connection: connection, channel: connection.createChannel() }))
并保持对连接的访问权限。
但是,还有另一种方法可以做你想做的事。让我们假设你的createConnection和createChannel函数看起来像这样:
function createConnection() {
return Rx.Observable.create(observer => {
console.log('creating connection');
const connection = {
createChannel: () => createChannel(),
close: () => console.log('disposing connection')
};
observer.onNext(connection);
return Rx.Disposable.create(() => connection.close());
});
}
function createChannel() {
return Rx.Observable.create(observer => {
const channel = {
send: x => console.log('sending message: ' + x)
};
observer.onNext(channel);
// assuming no cleanup here, don't need to return disposable
});
}
createConnection
(和createChannel
,但我们会关注前者)会返回一个冷的观察者;每个订阅者将获得包含单个连接的自己的连接流,并且当该订阅到期时,将自动调用dispose逻辑。
这允许你做这样的事情:
const subscription = createConnection()
.flatMap(connection => connection.createChannel())
.flatMap(channel => Rx.Observable.interval(1000).map(i => ({ channel: channel, data: i })))
.take(10)
.subscribe(x => x.channel.send(x.data))
;
您实际上不必处理订阅以进行清理;在take(10)
满意后,整个链将完成并将触发清理。您需要明确调用处理订阅的唯一原因是,如果您想在10个1000毫秒间隔之前解决问题。
请注意,此解决方案还包含对您的问题的直接答案的实例:我们将频道推到线下,以便我们可以在传递给订阅调用的onNext lambda中使用它(通常在此类代码出现的地方)
答案 1 :(得分:-1)
此代码给了我一个错误,因为flatmap等待 observable&lt;(T)&gt; 和({connection:connection,channel:connection.createChannel()} )它是一个对象。
.flatMap(connection => ({ connection: connection, channel: connection.createChannel() }))
您可以使用 combineLatest 运算符
.flatMap(connection => Observable.combineLatest( Observable.of(connection), connection.createChannel(), (connection, channel) => {
... code ....
});