使用HTTP + toPromise()时如何在Angular 2中设置超时?

时间:2016-06-16 16:09:35

标签: http angular

我发现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来检查新数据,但这不是我的问题,我只是想确保这种行为发生。

3 个答案:

答案 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)
}

来自Angular2 timeout in http post request

答案 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);