简体   繁体   English

取消订阅RxJS Observables

[英]Unsubscribe from RxJS Observables

I have these two objects, and I want to stop listening to their events. 我有这两个对象,我想停止听他们的事件。 I am totally new to observables and RxJS and just trying to work with the Inquirer library. 我对于observables和RxJS都很陌生,只是尝试使用Inquirer库。

Here is the RxJS API for reference: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html 以下是RxJS API供参考: http ://reactivex.io/rxjs/class/es6/Observable.js~Observable.html

How can I unsubscribe from these types of observables? 如何取消订阅这些类型的可观察量?

ConnectableObservable: ConnectableObservable:

   ConnectableObservable {
     source: EventPatternObservable { _add: [Function], _del: [Function], _fn: undefined },
     _connection: ConnectDisposable { _p: [Circular], _s: [Object] },
     _source: AnonymousObservable { source: [Object], __subscribe: [Function: subscribe] },
     _subject: 
      Subject {
        isDisposed: false,
        isStopped: false,
        observers: [Object],
        hasError: false } },
  _count: 1,
  _connectableSubscription: 
   ConnectDisposable {
     _p: 
      ConnectableObservable {
        source: [Object],
        _connection: [Circular],
        _source: [Object],
        _subject: [Object] },
     _s: AutoDetachObserver { isStopped: false, observer: [Object], m: [Object] } } }

FilterObservable: FilterObservable:

FilterObservable {
  source: 
   RefCountObservable {
     source: 
      ConnectableObservable {
        source: [Object],
        _connection: [Object],
        _source: [Object],
        _subject: [Object] },
     _count: 1,
     _connectableSubscription: ConnectDisposable { _p: [Object], _s: [Object] } },
  predicate: [Function] }

I need to unsubscribe from these objects: 我需要取消订阅这些对象:

'use strict';
var rx = require('rx');

function normalizeKeypressEvents(value, key) {
  return {value: value, key: key || {}};
}

module.exports = function (rl) {

  var keypress = rx.Observable.fromEvent(rl.input, 'keypress', normalizeKeypressEvents)
    .filter(function (e) {
      // Ignore `enter` key. On the readline, we only care about the `line` event.
      return e.key.name !== 'enter' && e.key.name !== 'return';
    });

  return {
    line: rx.Observable.fromEvent(rl, 'line'),

    keypress: keypress,

    normalizedLeftKey: keypress.filter(function (e) {
      return e.key.name === 'left';
    }).share(),

    normalizedRightKey: keypress.filter(function (e) {
      return e.key.name === 'right';
    }).share(),

    normalizedUpKey: keypress.filter(function (e) {
      return e.key.name === 'up' || e.key.name === 'k' || (e.key.name === 'p' && e.key.ctrl);
    }).share(),

    normalizedDownKey: keypress.filter(function (e) {
      return e.key.name === 'down' || e.key.name === 'j' || (e.key.name === 'n' && e.key.ctrl);
    }).share(),

    numberKey: keypress.filter(function (e) {
      return e.value && '123456789'.indexOf(e.value) >= 0;
    }).map(function (e) {
      return Number(e.value);
    }).share(),

    spaceKey: keypress.filter(function (e) {
      return e.key && e.key.name === 'space';
    }).share(),

    aKey: keypress.filter(function (e) {
      return e.key && e.key.name === 'a';
    }).share(),

    iKey: keypress.filter(function (e) {
      return e.key && e.key.name === 'i';
    }).share()
  };
};

My current best guess is that no explicit call to subscribe is happening like this: 我目前最好的猜测是没有明确的订阅调用发生在这样:

var source = Rx.Observable.fromEvent(input, 'click');

var subscription = source.subscribe(
  function (x) {
    console.log('Next: Clicked!');
  },
  function (err) {
    console.log('Error: %s', err);
  },
  function () {
    console.log('Completed');
  });

but instead, there are these calls: 但相反,有这些电话:

events.normalizedUpKey.takeUntil(validation.success).forEach(this.onUpKey.bind(this));
events.normalizedDownKey.takeUntil(validation.success).forEach(this.onDownKey.bind(this));

so my best guess is that I need a way to nullify/cancel the takeUntil call. 所以我最好的猜测是我需要一种方法来取消/取消takeUntil调用。

If you want to unsubscribe you need to have the Subscription object. 如果要取消订阅,则需要拥有Subscription对象。 That's the object returned from every Observable.subscribe() call. 这是从每个Observable.subscribe()调用返回的对象。 For example: 例如:

let subscriber = Observable.subscribe(...);
...
subscriber.unsubscribe();

For more info see: https://github.com/ReactiveX/rxjs/blob/master/doc/subscription.md 有关详细信息,请参阅: https//github.com/ReactiveX/rxjs/blob/master/doc/subscription.md

I second what the first commenter was saying. 我是第一个评论者说的第二个。 However it feels that there needs to be a call like this somewhere in the code: 但是感觉需要在代码中的某个地方进行这样的调用:

let subscription = normalizedUpKey.subscribe( data => console.log('data') );

that you could do 你能做到的

subscription.unsubscribe()

on. 上。 How else would you know when something happens, or is that part of the 3rd party library? 你怎么知道什么事情发生,或者是第三方图书馆的那部分?

To read more about Rxjs. 阅读更多关于Rxjs的信息。 I suggest you have a look at this free book, https://www.gitbook.com/book/chrisnoring/rxjs-5-ultimate/details 我建议你看看这本免费的书, https://www.gitbook.com/book/chrisnoring/rxjs-5-ultimate/details

There is no need and no protocol for unsubscribing from an observable. 从观察者中取消订阅没有必要也没有协议。 Actually, I see the code in your question, especially the part of the return object where a bunch of observables composed by share was included. 实际上,我在你的问题中看到了代码,特别是返回对象的一部分,其中包含了由share组成的一堆可观察对象。 However, these observables are still observables, rather than subscription, which means that there is no such concept called unsubscribing for these elements. 然而,这些可观察量仍然是可观察的,而不是订阅,这意味着没有这样的概念称为unsubscribing这些元素。

Therefore, if you have some new subscribe-like codes outside the module and exactly work with the events observables, you can obviously unsubscribe the specific subscription instance. 因此,如果您在模块外部有一些类似于订阅的新代码并且正好使用事件可观察对象,那么您显然可以取消订阅特定的订阅实例。

Currently, for the code in the question, the methods used on the source observable are all operators, such as .filter() .share() .takeUntil() , rather than subscribing execution, which are actually the methods return new observables. 目前,对于问题中的代码,source observable上使用的方法都是运算符,例如.filter() .share() .takeUntil() ,而不是订阅执行,实际上这些方法返回新的observable。

As described in the Rxjs official document, although .share() creates multicasted observables , it is still possible that the execution will stop if the number of subscribers decreases from 1 to 0 when using some convenient operators, where the .share() in your code is exactly included as well. 如Rxjs官方文档中所述,虽然.share()创建了多播observable ,但是当使用一些方便的运算符时,如果订阅者数量从1减少到0 ,执行仍然可能会停止,其中.share()在你的代码也完全包含在内。

In conclusion, there is no need to worry about the event unsubscribing for your code in your question. 总之,您无需担心在您的问题中取消订阅代码的事件。 Potentially, there is really a further problem which sounds like the concern described in your question: If you use .connect() instead of .share() . 潜在的,确实这听起来像你的问题中所描述的关注另一个问题:如果你使用.connect()代替.share() It is the situation about ConnectableObservable where you need to concern about manually canceling event binding. 这是关于ConnectableObservable的情况,您需要关注手动取消事件绑定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM