我发现this answer建议的解决方案是使用 Observables 来设置http请求'超时。
然而,我的代码的结构主要是使用promises(我使用observables,我想让数据自动更新 - 这不是API调用的情况)。
这是我的代码(受Angular 2教程启发):
makePostRequest(requestUrl:string, requestBody: any, requestOptions?: RequestOptions): Promise<any> {
requestOptions = requestOptions || new RequestOptions({ headers: this._defaultHeaders });
return this._http.post(requestUrl, JSON.stringify(requestBody), requestOptions)
.toPromise()
.then(this.extractData)
.catch(this.handleError)
}
如何设置超时并抛出错误(如果超时到期),然后我将其捕获到.catch()或 - 或者 - 使用Observables复制精确的行为(包括将结果转换为Promise 而不是监控API更新(*)的监控??
(*)注意:我不确定Observable是否继续调用API来检查新数据,但这不是我的问题,我只是想确保这种行为不发生。
答案 0 :(得分:3)
我希望这可以做你想要的(没试过):
makePostRequest(requestUrl:string, requestBody: any, requestOptions?: RequestOptions): Promise<any> {
requestOptions = requestOptions || new RequestOptions({ headers: this._defaultHeaders });
return this._http.post(requestUrl, JSON.stringify(requestBody), requestOptions)
.timeout(3000, new Error('timeout exceeded'))
.toPromise()
.then(this.extractData)
.catch(this.handleError)
}
答案 1 :(得分:2)
解决方案(右链+进口)我发现:
// ! must import these
...
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
return this._http.get(requestUrl, requestOptions)
.timeout(5000, new Error( 'HTTP (GET) timeout for path: ' + requestUrl))
.map(this.extractData)
.toPromise()
.catch(this.handleError);
答案 2 :(得分:0)
我对此有所不同。我的逻辑依赖于返回的承诺 - 并且.timeout
使得它立即失败,无论超时持续时间如何。
我的解决方案是创建一个新的承诺,而不是使用toPromise
:
const timeoutInMs = 3000;
const request = this._http
.post(/* ... */)
.timeout(timeoutInMs);
return new Promise((resolve, reject) => {
request
.take(1)
.subscribe(
data => resolve(data),
error => reject(error),
);
});
如果您经常使用它,可以将其重构为函数(尚未测试):
const toPromiseWithTimeout = <T>(obs: Observable<T>, ms): Promise<T> =>
new Promise<T>((resolve, reject) => {
obs
.timeout(ms)
.take(1)
.subscribe(
data => resolve(data),
error => reject(error),
);
});
使用它:
const timeoutInMs = 3000;
const request = this._http
.post<ResponseType>(/* ... */);
return toPromiseWithTimeout(request, timeoutInMs);