【问题标题】:How to set a timeout in Angular 2 when using HTTP + toPromise()?使用 HTTP + toPromise() 时如何在 Angular 2 中设置超时?
【发布时间】:2016-06-16 16:09:35
【问题描述】:

我发现this answer 提出的解决方案是使用Observables 来设置http 请求的超时时间。

但是,我的代码结构主要使用 Promise(我使用 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 更新 (*)) 的监控?

(*) 注意:我不确定 Observables 是否继续调用 API 来检查新数据,但这不是我的问题的重点,我只是想确保这种行为不会 发生。

【问题讨论】:

    标签: http angular


    【解决方案1】:

    我希望这可以满足您的要求(未尝试过):

    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

    【讨论】:

    • 已经试过了。显然只有 observables 支持超时
    • 那行不通?这里解释了如何使 Promise stackoverflow.com/questions/32461271/… 超时我不知道如何在您的情况下使用它,因为您没有创建 Promise。你需要做类似return new Promise((resolve, reject) =&gt; { http.post().subscribe(... resolve(), error =&gt; reject())})
    • 我不记得这个特定情况下的确切错误,但我记得原因:超时仅在可观察链中有效,没有承诺。
    • 我会在接下来的几天里做一些其他的尝试。现在我会为这项努力投票:)
    • 我找到了解决方案(我回答了我自己的问题)。你的回答几乎是正确的。但正确的 requence 是首先 map,然后是 toPromise,最后是 catch,负责导入必要的 rxjs 操作符。
    【解决方案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);
    

    【讨论】:

      【解决方案3】:

      我的处理方式有点不同。我的逻辑依赖于返回的承诺 - 并且执行 .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);
      

      【讨论】:

        猜你喜欢
        • 2017-05-18
        • 2017-10-21
        • 2014-03-21
        • 1970-01-01
        • 1970-01-01
        • 2016-10-30
        • 2019-06-25
        • 1970-01-01
        • 2017-05-31
        相关资源
        最近更新 更多