【问题标题】:RxJS detect when observable has been subscribed toRxJS 检测 observable 何时被订阅
【发布时间】:2017-06-14 22:20:39
【问题描述】:

我需要检测何时订阅了 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>

这可能吗?

我希望这能解释我在寻找什么。

在我写这篇文章时,我在想一个带有 Subjects 的解决方案可能是我需要的。我不确定,但如果可能的话,我只需要朝着正确的方向轻推或找到解决方案。

【问题讨论】:

    标签: javascript ecmascript-6 observable reactivex


    【解决方案1】:

    果然我使用主题是正确的。关键是 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>

    【讨论】:

    • observers 现在被标记为已弃用,在第 8 版中是内部的。正在寻找解决此问题的方法...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2016-12-20
    • 2021-11-16
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多