在Angular 2中重试连接到服务器回调失败
问题描述:
在我的API父类中,我实现了与服务器通信所需的所有方法。在Angular 2中重试连接到服务器回调失败
@Injectable()
export class ApiService {
constructor(protected http: Http,
protected snackBar: MdSnackBar) {
}
get<T>(resourceUrl: string, queryOptions?: { [key: string]: any; }): Observable<T> {
this.progressBarService.show();
const endpoint = resourceUrl + this.createQueryString(queryOptions);
const callback =() => { return this.get<T>(resourceUrl, queryOptions); };
return this.http.get(endpoint)
.map(this.extractData)
.catch((err: Response, caught: Observable<T>) => {
return this.catchError(err, this.snackBar, callback);
})
.finally(() => {
this.progressBarService.hide();
});
}
protected catchError(error: Response | any, snackBar: MdSnackBar, callback: Function) {
if (!environment.production) {
console.error(error);
}
const errorMsg = 'Error while connecting the server.';
const snackBarRef = snackBar.open(errorMsg, 'Retry', {duration: 3000});
snackBarRef.onAction().subscribe(() => {
callback();
});
return Observable.throw(errorMsg);
}
}
如果错误发生了,我正在使用的catchError()
函数来显示一个snackBar
使用静态消息的用户。如果用户点击“重试”按钮,我使用回调函数重试连接。在catchError
函数中使用callback()
函数什么也没有发生。我确定callback
被调用,因为我甚至尝试在其中放置一些console.log()
,我可以在控制台上看到消息。
答
喜欢的东西...
get<T>(resourceUrl: string, queryOptions?: { [key: string]: any; }, subject: Subject<T> = null): Observable<T> {
this.progressBarService.show();
const endpoint = resourceUrl + this.createQueryString(queryOptions);
subject = subject || new Subject<T>();
const callback =() => { return this.get<T>(resourceUrl, queryOptions, subject); };
let obs = this.http.get(endpoint)
.map(this.extractData)
.catch((err: Response, caught: Observable<T>) => {
return this.catchError(err, this.snackBar, callback);
});
obs.subscribe(res => {
this.progressBarService.hide();
subject.next(res);
subject.complete();
});
return subject;
}
我会改变的唯一的事情是,如果用户以某种方式决定不重新发出请求,你应该叫subject.error()
清理对象,并通知所有侦听他们永远不会得到答案。
我认为你的问题是第一次调用返回一个可能是(可能)订阅的observable。第二个调用也返回一个可观察对象,但可能没有人正在订阅它。 – Pace
任何想法如何解决这个问题?也许增加一个'share()'? – Bagbyte
对不起,太累了,今晚没有提供完整的答案。想到的一个方法是创建一个主题。每次你打电话给get然后订阅它(在'get'方法中)并发布到主题。然后返回主题。 –
Pace