我需要检测何时订阅了一个observable(observedEvents
),订阅另一个observable(triggerEvent
)。我不想手动订阅triggerEvent
,但仅在observedEvents
订阅时才订阅。
以下是一些解释我要找的内容的代码:
// This just emits events
let emitting = new EventEmitter();
// This is the main Observable which someone else might
// have access to
let observedEvents = Rx.Observable.merge(
Rx.Observable.fromEvent(emitting, 'aba'),
Rx.Observable.fromEvent(emitting, 'bob')
)
// This trigger should get a subscription if observedEvents
// has one, i.e. when I subscribe to observedEvents
// that subscription activates this trigger
// I have made an attempt at this by calling skipUntil
// this however skips one event, but I don't want that
let triggerEvent = Rx.Observable.merge(
// these actions are things that can
// happen when the trigger is active
Rx.Observable.of('a').delay(200),
Rx.Observable.of('b').delay(400),
Rx.Observable.of('c').delay(600)
)
.skipUntil(observedEvents);
// Something else should be used to activate trigger
// I don't want to do this part manually
triggerEvent.subscribe(val => {
console.log(`Do something fancy with ${val}`);
});
//----------------------------------------------------
// Somewhere else in the code...
//----------------------------------------------------
observedEvents.subscribe(evt => {
console.log(`Some event: ${evt}`);
});
// At this point I want triggerEvent to become active
// because observedEvents has a subscription
setTimeout(() => {
emitting.emit('bob', 'world');
setTimeout(() => emitting.emit('aba', 'stackoverflow!'), 500);
}, 200);
<!DOCTYPE html>
<html>
<head>
<script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.7/dist/global/Rx.umd.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/EventEmitter/5.1.0/EventEmitter.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
</body>
</html>
这可能吗?
我希望这能解释我在寻找什么。
正如我写的那样,我认为主题的解决方案可能就是我需要的。我不确定,但如果可能的话,我只需要朝着正确的方向推进或者解决方案。
答案 0 :(得分:4)
我确实使用主题是正确的。关键是Subject的观察者名单。这是我最终做的:
let emitting = new EventEmitter();
let sub = new Rx.Subject();
// return this to users
let myGlobalSub = sub.merge(Rx.Observable.of(1, 2, 3));
// For internal use
let myObservers = Rx.Observable.fromEvent(emitting, 'evt');
console.log(`The number of subscribers is ${sub.observers.length}`);
// Only do something if myGlobalSub has subscribers
myObservers.subscribe(l => {
if (sub.observers.length) { // here we check observers
console.log(l);
}
});
// Somewhere in the code...
emitting.emit('evt', 'I don\'t want to see this'); // No output because no subscribers
myGlobalSub.subscribe(l => console.log(l)); // One sub
emitting.emit('evt', 'I want to see this'); // Output because of one sub
console.log(`The number of subscribers is ${sub.observers.length}`);
<!DOCTYPE html>
<html lang=en>
<head>
<script src="https://unpkg.com/rxjs@5.5.11/bundles/Rx.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/EventEmitter/5.2.5/EventEmitter.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
</body>
</html>