rxjs可观察:处理所有订阅的退订

时间:2018-10-26 13:11:11

标签: javascript rxjs

我有一个返回Observable的方法

subFoo(id): Observable<number> {
    return new Observable<number>(observer => {
        setTimeout(() => {
            observer.next(id);
        }, 1000);
    });
}

现在我订阅了3次,并在5秒钟后全部取消订阅:

const sub1 = subFoo(1).subscribe(result => console.log(result));
const sub2 = subFoo(2).subscribe(result => console.log(result));
const sub3 = subFoo(3).subscribe(result => console.log(result));

setTimeout(() => {
  sub1.unsubscribe();
  sub2.unsubscribe();
  sub3.unsubscribe();
}, 5000);

我可以处理所有列出者的完全取消订阅吗?

例如(以伪代码):

subFoo(id): Observable<number> {
    return new Observable<number>(observer => {

        // something like this
        observer.onAllListenerAreUnsubscribed(() => {
           console.log('All Listener Are Unsubscribed!');
        });

        setTimeout(() => {
            observer.next(id);
        }, 1000);
    });
}

实时演示:https://stackblitz.com/edit/angular-ayl12r

3 个答案:

答案 0 :(得分:1)

Observable可以知道对其链的订阅。如果您想知道某人订阅了多少次,可以自己计算:

                                  C
              Phone <phone_numbers>
               email <adresse_mail>
                  my name is <name>
                       Hello <name>
<name>, my phone is <phone_numbers>

您还可以将“观察者侧”的所有订阅收集到一个订阅中,然后在取消订阅时添加自定义处理程序:

let subscriptions = 0;

subFoo(id): Observable<number> {
  return new Observable<number>(observer => {
    subscriptions++;
    ...
    return (() => {
      if (--subscriptions === 0) {
        // do whatever...
      }
      ...
    })
  })
})

答案 1 :(得分:1)

您可以在一行中取消订阅所有侦听器,因此无需处理该事件

subscriptions.add(sub1).add(sub2).add(sub3);

// Then unsubscribe all of them with a single 
subscriptions.unsubscribe();

答案 2 :(得分:1)

通过一次完成所有可观察的数据,可以确保不会泄漏任何数据。 您可以创建一个将在可观察对象停止发送后发出的主题,并在可观察对象上使用takeUntil()运算符,如下所示:

const completeSubscription: Subject<void> = new Subject();

const sub1 = subFoo(1)
  .pipe(takeUntil(completeSubscription))
  .subscribe(result => console.log(result));
const sub2 = subFoo(2)
  .pipe(takeUntil(completeSubscription))
  .subscribe(result => console.log(result));
const sub3 = subFoo(3)
  .pipe(takeUntil(completeSubscription))
  .subscribe(result => console.log(result));

setTimeout(() => {
  completeSubscription.next();
  completeSubscription.complete();
}, 5000);