【问题标题】:Angular $http : setting a promise on the 'timeout' configAngular $http:在“超时”配置上设置承诺
【发布时间】:2014-03-21 20:52:41
【问题描述】:

在 Angular $http docs 中,它提到您可以将“超时”配置设置为数字或承诺。

timeout – {number|Promise} – 以毫秒为单位的超时,或承诺 解决后应该中止请求。

但我不确定如何使用承诺来完成这项工作。我如何设置数字和承诺? 基本上,我希望能够知道 http 调用(承诺)是否由于“超时”或其他原因而出错。我需要能够区分。 感谢您的帮助!!!

【问题讨论】:

    标签: angularjs promise


    【解决方案1】:

    此代码来自$httpBackend source code:

    if (timeout > 0) {
      var timeoutId = $browserDefer(timeoutRequest, timeout);
    } else if (timeout && timeout.then) {
      timeout.then(timeoutRequest);
    }
    
    function timeoutRequest() {
      status = ABORTED;
      jsonpDone && jsonpDone();
      xhr && xhr.abort();
    }
    

    timeout.then(timeoutRequest) 表示当 promise 被解决(不是拒绝)时 timeoutRequest 被调用并且 xhr 请求被中止。


    如果请求超时则reject.status === 0注意:如果网络故障,则reject.status也将等于0),示例:

    app.run(function($http, $q, $timeout){
    
      var deferred = $q.defer();
    
      $http.get('/path/to/api', { timeout: deferred.promise })
        .then(function(){
          // success handler
        },function(reject){
          // error handler            
          if(reject.status === 0) {
             // $http timeout
          } else {
             // response error status from server 
          }
        });
    
      $timeout(function() {
        deferred.resolve(); // this aborts the request!
      }, 1000);
    });
    

    【讨论】:

    • 您还可以检查 statusText 值,该值将是 "unknown" github.com/angular/angular.js/blob/v1.2.23/src/ng/… 例如。 if (reject.status === 0 && reject.statusText === 'unknown') { ... 应该仔细考虑,它是无证的。
    • 其实"unknown"只存在于jsonp中。
    • 在 1.4.8 中,无论我解决还是拒绝承诺,XHR 都会中止。但问题是我无法将任何数据传递给拒绝方法,比如我的拦截器。
    • 当我从我的函数中deferred.reject('timeout') 时,我的控制器中没有超时作为响应。它总是未定义的。知道为什么会这样吗?我在$timeout 中使用deferred.reject();
    • @JayeshJain 你能做一个 plnkr 吗?
    【解决方案2】:

    我有一个类似的问题,您可以查看此链接:Angular 1.5 timeout using a HttpInterceptor,了解如何在 httpInterceptor 中实现超时。 jsFiddle 包含在 anwser 中。所有功劳都归于https://stackoverflow.com/users/3959997/mita 以获得答案。

    【讨论】:

      【解决方案3】:

      我正在研究嵌入式系统,并且由于它是物理设备,所以我不时进行闲逛,因此使用 $timeout 修复了此行为,它会保持开启数天/数月/数年

      快速示例(http 承诺的超时包装器)

      模块

      var myApp = angular.module('myApp',['ngRoute']);
      

      服务

      var yourServiceModule = myApp.service('YourService', function ($http) {
          this.your_method = function (a) { return a*a};
      });
      

      控制器

      //just wrap your service,http call using $timeout
      $timeout(function() {
          //vanilla service call
          YourService.your_method().then(
                    function (response) {
                       //console.log("sync_with_cloud: "+ response);
                       $scope.check_cloud_port_statuses_progress=100;
                       //...
                   },
                    function(data) {
                        // Handle error here
      
                      $rootScope.global_config_1 += "\nError(333): cant connect to cloud at "+Date.now();+"\n\n";
                      $scope.check_cloud_port_statuses_progress = -1;
                    }
          );
      
      }, 8);
      

      【讨论】:

        猜你喜欢
        • 2020-03-17
        • 1970-01-01
        • 2016-10-30
        • 2015-07-09
        • 1970-01-01
        • 2015-08-26
        • 1970-01-01
        • 1970-01-01
        • 2013-08-28
        相关资源
        最近更新 更多