在可观察对象上附加“订阅回调函数”

3

我的Angular 4应用程序有一个REST服务,注入到各种组件中并返回Observables。在一个特定的组件中,我想要知道挂起请求的数量。目前,我是通过在发出请求时增加计数器,在请求完成(成功或失败)时减少计数器来实现这个目的的。就像这样:

export class MyComponent {
    nRunningRequests = 0;

    constructor(private restService: RestService) {
    }

    loadData(type: string): Observable<any> {
        // this line is wrongly executed too soon, since the request
        // is not actually done yet
        this.nRunningRequests++;
        return this.restService.fetchData(type)
            .finally(() => this.nRunningOperations--);
    }

    loadNames(): Observable<any> {
        this.loadData('names');
        // oops, didn't subscribe, so no request is actually being done
        // but nRunningRequests is now wrong
    }
}

我遇到的问题是,如果我没有实际调用subscribe()来订阅可观察者对象,那么就不会触发任何请求,因此计数器不应该增加。有没有一种方式可以附加一个回调,在订阅时调用?类似于以下内容:
    loadData(type: string): Observable<any> {
        return this.restService.fetchData(type)
            .initially(() => this.nRunningRequests++)
            .finally(() => this.nRunningRequests--);
    }

我也可以将计数逻辑移动到REST服务中,但这没有意义,因为我只想计算来自这个组件的请求。

1个回答

2
在一些 RxJS 变体中,可能有你需要的内容(也许在 RxJS 4 中也是如此,现在我不确定),但在 RxJS 5 中没有作为操作符提供。
实现你想要的最简单的方法是使用 Observable.defer 创建源 Observable:
Observable.defer(() => {
    this.nRunningRequests++
    return this.restService.fetchData(type)
  })
  .finally(() => this.nRunningRequests--);

所以基本上 defer 允许在订阅建立之前执行副作用,对吗? - Max Koretskyi
非常好,非常感谢!我认为即使有多个订阅者,这也将正常工作。 - jlh
1
@Maximus 我不认为defer的主要目的是如此,但基本上是这样。当您想要控制链中将成为源Observable的内容时,它最有用。例如,如果您正在使用Angular的http服务,则可以为每个请求设置不同的标头。 - martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接