情况:
我遇到了rxjs Observable
系统的用例,在其中,我可能需要在pipe
启动后向Subscription
添加Subscription
d命令。
就我而言,我正在处理的应用程序必须被动地监听推送通知系统。可以在此系统上推送许多消息,我的系统需要对此消息做出响应。 但是,在可预见的情况下,将来将要实现的动态加载视图将需要在推送通知系统中添加侦听器。
问题:
假设我的应用处于我的.subscribe(() => {})
已经存在的状态,是否可以在调用// this.something is an Observable<any>, for discussion purposes.
const subscription = this.something.subscribe(() => { // commands });
this.something.pipe(
map((something) => {
// ...Commands that I want to add to the subscription...
})
);
之后添加其他管道?
foo_DEV
...如果我这样做,那会发生什么,如果有的话?
解决方案:
@ user2216584和@SerejaBogolubov的两个答案都回答了这个问题。
我的高级推送通知侦听器服务需要做两件事:
复杂的是每个侦听器都需要侦听不同的消息。换句话说,如果我在bar_DEV
上收到消息,则应用程序需要做的事情与推送通知系统在export interface PushNotificationListener {
name: string,
onMessageReceived: (msg: PushNotificationMessage) => any,
messageSubject$: Subject<PushNotificationMessage>
}
export class PushNotificationListenerService {
private connection$: Observable<PushNotificationConnection>;
private subscription$: Subscription;
private listeners: PushNotificationListener[] = [];
constructor(
private connectionManager: PushNotificationConnectionManager
) {
}
connect() {
// Step 1 - Open the socket connection!
this.connection$ = this.connectionManager.connect(
// The arguments for setting up the websocket are unimportant here.
// The underlying implementation is similarly unimportant.
);
}
setListener(
name: string,
onMessageReceived: (msg: PushNotificationMessage) => any
) {
// Step 3...or maybe 2...(shrug)...
// Set listeners that the subscription to the high-order connection
// will employ.
const newListener: PushNotificationListener = {
name: name,
onMessageReceived: onMessageReceived,
messageSubject$: null
};
this.listeners.push(newListener);
}
listen() {
// Step 2 - Listen for changes to the high-order connection observable.
this.subscription$ = this.connection$
.subscribe((connection: PushNotificationConnection) => {
console.info('Push notification connection established');
for (let listener of this.listeners) {
listener.messageSubject$ = connection.subscribe(listener.name);
listener.messageSubject$.subscribe((message: PushNotificationMessage) => {
listener.onMessageReceived(message);
}
}
},
(error: any) => {
console.warn('Push notification connection error', error);
}
}
}
上推送消息的事情有所不同。
所以,这是我想出的:
Observable
通过仔细研究构成推送通知系统核心的内部代码,我发现我们已经有了一个高阶connectionManager.connect()
。 websocket代码创建了一个可观察的(subscribe
),需要将其缓存在服务中并进行订阅。由于该代码特定于我的工作地点,因此不再赘述。
但是,缓存侦听器也很重要!每当连接更改状态时,.listen()
中的.addListener()
调用都会遍历所有连接的侦听器,因此我可以通过Observable
临时添加侦听器,这是因为rxjs的{{1 }}系统固有地起作用,并且事实上,我是在一个范围内的侦听器列表中工作的,所以我有一个系统可以动态设置侦听器,即使调用了.connect()
在配置任何侦听器之前。
此代码可能仍然可以从重新设计/重构中受益,但是我有一些可行的方法,这是任何好的编码的重要第一步。谢谢大家!
答案 0 :(得分:3)
[我正在编辑我的答案,因为先前的答案是根据作者共享的第一个代码;如评论中所述,作者已更改/更正了代码]-
我怀疑以下代码是否会影响订阅中的任何内容-
this.something.pipe(
map((something) => {
// ...Commands that I want to add to the subscription...
})
);
您可以在最初设置可观察的对象时尝试使用高阶函数,如果高阶函数在范围内,则可以重新分配它。我还怀疑它是否可以工作,原因如下-
设置Observable时,observable保留传递的函数的引用,该函数将在订阅[{https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87]]上调用。现在,如果您重新分配高阶函数,那么可观察函数仍然指向旧参考。通过重新分配高阶函数,您没有更改最初设置可观察对象时设置的原始函数引用。
假定由于某种原因,高阶重新分配有效,在这种情况下,也很有可能在执行旧的高阶函数之前,您可能已经重新分配了高阶函数(因为如果源可观察到异步调用后端,在等待代码时,javascript事件循环可能已重新分配了高阶函数,当异步调用返回时,它将执行新分配的高阶函数。也许这段代码会阐明我的观点-
让highOrderFunc = map(x => x * 2);
this.something
.pipe(
mergeMap(_ => //call to backend; async call),
higherOrderFunc,
).subscribe();
higherOrderFunc = map(x => x * 3); // this will execute before async call completes
答案 1 :(得分:2)
好吧,您可以轻松完成。假设您想要一些延迟运行的map
。比起map(this.myMapper)
来说,myMapper
是在适当范围内可见的私有字段。通过更改该私有字段,您可以添加/删除其他行为。例如,map(x => x)
表示没有任何映射。
但是,在我看来,您正在滥用rxjs
。最有可能您真正需要的是高阶可观察的(发出可观察的“流”的可观察的)。那将是更rxjs
更干净的解决方案。所以请三思。