是否可以将Teardown逻辑添加到已存在的Observable中?

时间:2016-08-24 05:22:50

标签: rxjs5

例如,我正在调用取消订阅从Angular 2的HTTP返回的Observable。

但我有一些围绕它的自定义逻辑。

是否可以将自定义拆卸逻辑添加到已存在的Observable,例如从Angular 2的HTTP返回的那个?

Observable.prototype.whenUnsubscribed(customTeardownLogic)的内容可能是什么?

3 个答案:

答案 0 :(得分:3)

要回答确切的问题,不,您不能将拆卸逻辑添加到现有的 可观察

但是,对于 观察者 的可观察对象(您可能已经或可能无法控制)和拆除逻辑的拆卸逻辑 - 即您的订阅 - 是你的管理。

听起来你想使用add()方法使用后一个拆卸逻辑:

anyObservable.subscribe(function() {

  // my observer code

}).add(function() {

  // my teardown logic

});

上面我已经演示了使用拆卸逻辑的功能,但也可以发送订阅,这提供了一种简单的方法来取消订阅任何数量的其他订阅(当完成/错误)时。

请注意,如果在添加拆卸逻辑时observable处于关闭状态,它将立即执行。

答案 1 :(得分:2)

这可能不是您想要的,但可能有所帮助:

假设您有类似的内容(取自Angular 2网站上的the Hero Guide):

(打字稿)

@Injectable()
export class HeroService {
  private heroesUrl = 'api/heroes';  // URL to web API
  constructor (private http: Http) {}
  getHeroes(): Observable<Hero[]> {
    return this.http.get(this.heroesUrl)
                    .map(this.extractData);
  }
  private extractData(res: Response) {
    let body = res.json();
    return body.data || { };
  }
}

// And somewhere else in your code you do:

let subscription = service.getHeroes().subscribe( ... do stuff here );

// And later on you do:

subscription.unsubscribe();

如果你想添加一些自定义拆卸逻辑,你可以将Angular 2返回的Observable包装成你自己的:

getHeroes(): Observable<Hero[]> {
    return Observable.create(
        //Let's provide a subscribe function
        (observer: any) => { 
            const subscription = this.http.get(this.heroesUrl)
                        .map(this.extractData).subscribe(observer);

            // Now let's return a tear-down/unsubscribe function
            return () => {
                subscription.unsubscribe();
                this.myTearDownLogic();
            }
        }
     );

答案 2 :(得分:0)

聚会有点晚了,但这是我的两分钱:创建一个可重用的运算符!

它与 Angular 异步管道或多个组件的服务一起使用很方便。

teardown.ts

export function teardown<T>(afterEachCb: () => void, afterAllCb?: () => void) {
  let subscriberCount = 0;
  return (source: Observable<T>): Observable<T> => {
    return new Observable((subscriber) => {
      const subscription = source.subscribe(subscriber);
      subscriberCount += 1;

      return () => {
        subscription.unsubscribe();
        subscriberCount -= 1;
        afterEachCb();
        if (subscriberCount === 0) {
          afterAllCb();
        }
      };
    });
  };
}

您可以按如下方式使用它:

heroes.component.ts(摘录)

this.heroes$ = this.heroService.getHeroes().pipe(
  teardown(() => {
    // custom teardown logic here
  })
);

heroes.component.html(摘录)

<app-hero [hero]="hero" *ngFor="let hero of heroes$ | async"></app-hero>

免责声明:我没有在所有场景中测试过。我用它来提供一个 WakelockService,它会在没有更多组件请求时自动释放唤醒锁(通过订阅)。