如何订阅要返回的 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})
);
}
虽然第二个可能看起来有点冗长,但它的优点是实际上只在请求 开始 时更新挂起的请求计数器,即当它被订阅时(在第一次迭代它在函数调用时递增,这与订阅不同)。
此外,它允许您围绕该请求对象放置任何您想要的附加逻辑(考虑时间或指标),而无需求助于副作用变量。
我有一个扩展 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})
);
}
虽然第二个可能看起来有点冗长,但它的优点是实际上只在请求 开始 时更新挂起的请求计数器,即当它被订阅时(在第一次迭代它在函数调用时递增,这与订阅不同)。
此外,它允许您围绕该请求对象放置任何您想要的附加逻辑(考虑时间或指标),而无需求助于副作用变量。