如何订阅要返回的 Observable,同时仍然返回 Observable

How to subscribe to an Observable that is to be returned, while still returning an Observable

我有一个扩展 Http 的 AuthHttpService。每当发出请求时,我 return Observable,但我也想在 HTTPService 本身内部采取一些行动。我该怎么做呢?

例如:

  get(url: string) {
    this.pendingRequests++;
    return this.http.get(this.config.apiUrl + '' + url, { headers: this.getHeaders(this.config.apiUrl + url) })
      .subscribe(() => {
        if (this.pendingRequests > 0) {
          this.pendingRequests--;
        }
      });

  }

我正在使用 this.pendingRequests > 0 来显示加载微调器。我想将实际响应传回给任何名为 authHttp.get() 的服务,但我希望 authHttp 自行管理 pendingRequests,那么我如何在不订阅的情况下使用它做一些事情?我调用此方法的服务抱怨 Property 'map' does not exist on type 'Subscription',这是有道理的,但我不知道该怎么做。

错误来自组件的服务调用 AuthHttp.get,期望 Observable,但却获得了订阅。我想知道 AuthHttp 是否有任何订阅方式,但仍然 return 订阅

根据@silentsod 的建议,我现在正在创建可观察对象,订阅它,然后返回它。

let req = this.http.put(
  this.config.apiUrl + '' + url, JSON.stringify(this.request),
  { headers: this.getHeaders(this.config.apiUrl + url + JSON.stringify(this.request)) }
)
  .catch(err => {
    if (err.status === 401 || err.status === 403) {
      let res: Response = err;
      window.location.replace(this.config.membershipUrl +
        '/#/Home?ReturnURL=' + this.config.appUrl + '/#/authorize&appID=24B89F21-54ED-4073-94AA-BDC354668667');
      return Observable.of(res.json());
    } else if (err.status === 500) {
      this.router.navigateByUrl('/error');
    }
  });
req.subscribe(() => {
  if (this.pendingRequests.getValue() > 0) {
    pending = this.pendingRequests.getValue();
    this.pendingRequests.next(pending - 1);
  }
});
return req;

最简单的方法是通过 do 块应用 "side-effect"

  get(url: string) {
    this.pendingRequests++;
    return this.http.get(this.config.apiUrl + '' + url, { headers: this.getHeaders(this.config.apiUrl + url) })
      .do(() => {
        this.pendingRequests = Math.max(0, this.pendingRequest - 1);
      });
  }

您可以选择更高级并使用 Subscription 包装每个请求:

const PendingRequest = (onStart, onFinish) => {
  onStart();
  return onFinish;
}

const defaultRequest = () => PendingRequest(
  () => this.pendingRequest++,
  () => this.pendingRequests = Math.min(0, this.pendingRequests - 1)
);

get(url: string) {
  return Observable.using(
    defaultRequest,
    pendingRequest => this.http.get(url, {headers})
  );
}

虽然第二个可能看起来有点冗长,但它的优点是实际上只在请求 开始 时更新挂起的请求计数器,即当它被订阅时(在第一次迭代它在函数调用时递增,这与订阅不同)。

此外,它允许您围绕该请求对象放置任何您想要的附加逻辑(考虑时间或指标),而无需求助于副作用变量。