typescript 是否可以将拆卸逻辑添加到已经存在的观察对象中?

cgh8pdjw  于 2023-02-20  发布在  TypeScript
关注(0)|答案(5)|浏览(115)

例如,我当前正在从Angular 2的HTTP模块返回的Observable调用unsubscribe
但我需要一些自定义的逻辑围绕它。
是否可以向已经存在的Observable添加自定义拆卸逻辑,比如从Angular 2的HTTP模块返回的逻辑?
大致是这样的:

Observable.prototype.whenUnsubscribed(customTeardownLogic)
ohtdti5x

ohtdti5x1#

要准确回答所问的问题,不可以,您不能将拆卸逻辑添加到现有的***observable***中。
然而,对于可观察对象(您可以控制也可以不控制)和***观察者***(即您的订阅,由您来管理),都存在拆卸逻辑。
听起来像是要使用add()方法来使用后一种拆卸逻辑:

anyObservable.subscribe(function() {

  // my observer code

}).add(function() {

  // my teardown logic

});

上面我已经演示了如何使用一个函数来实现拆卸逻辑,但是也可以发送订阅,这提供了一种简单的方法,可以在这个订阅关闭(完成/错误)时取消订阅任意数量的其他订阅。
请注意,如果在添加拆卸逻辑时观察对象处于关闭状态,则它将立即执行。

irtuqstp

irtuqstp2#

这可能不是你想要的,但它可能会有所帮助:
假设你有这样的东西(取自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 || { };
    }
}

// Somewhere else in your code you do:
let subscription = service.getHeroes().subscribe(/* do stuff here */);

// ...and later on:
subscription.unsubscribe();

如果你想添加一些自定义的拆卸逻辑,你可以用你自己的逻辑来 Package 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);

            // Return a tear-down/unsubscribe function
            return () => {
                subscription.unsubscribe();
                this.myTearDownLogic();
            }
        }
     );
}
jexiocij

jexiocij3#

TL;DR:

假设一个function teardown()保存了您的拆卸逻辑,您需要增强这个original: Observable

new Observable(
  sub => original.subscribe(sub).add(() => teardown())
)

一个简单、傻瓜式的一行程序

本节仅解释 TL中的代码;DR: 见上文。
其实有一个办法
只需使用您的额外TeardownLogic创建一个 * 新 * Observable,并让其订阅实际订阅您的original

const original: Observable<T> = // [...]
return new Observable(subscription => {
  // Add custom teardown logic
  subscription.add(() => teardown());

  // Delegate to the original `Observable`
  original.subscribe(subscription);
});

您还可以简单地提供TeardownLogic回调,作为传递给new Observable构造函数的订阅处理程序的结果:

const original: Observable<T> = // [...]
return new Observable(subscription => {
  // Delegate to the original `Observable`
  original.subscribe(subscription);

  // Define the teardown logic here
  return () => teardown();
});

还有

如果可以的话,不要犹豫,实际上内联originalObservable

new Observable(
   sub => fromEvent(document, 'click').subscribe(sub).add(() => teardown())
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//         your `original` Observable
)
w8f9ii69

w8f9ii694#

派对来晚了点,但我的意见是:创建一个可重用的操作符!
它可以方便地与Angular 异步管道,或服务的多个组件。

拆卸.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();
        }
      };
    });
  };
}

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

英雄.组件.ts(摘录)

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

英雄.组件.html(摘录)

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

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

bmvo0sr5

bmvo0sr55#

答案是简单的否定
所有其他的答案都没有提供一种方法来将拆卸逻辑注入到已经存在/创建的不受您控制的Observable中(例如,可以从Angular HttpClient订阅的Observable)。
你怎么能为一个在你不控制的模块中创建的Observable添加/注入teardown逻辑呢?
其他的答案提供了一些方法,当你取消订阅可观察对象时,可以添加一些要执行的逻辑,但无论如何不能“影响”原始可观察对象的拆卸逻辑。
仅当使用new Observable(...)Observable.create(...)创建观察对象时,才能提供拆卸逻辑

相关问题