异步调用:在收到第一个" pending"服务器响应

时间:2015-07-24 11:15:13

标签: angularjs asynchronous

我有一个异步的Web服务,它将返回状态" pending"直到它返回200或错误。 到目前为止,这是我的代码:

        $http.get('/myweb/services/callService').success(function(response, status, headers, config){
            ...handling success

        }).error(function(err, status, headers, config){
            //handling failure
        });

        //called just after $http.get
        $scope.askProgress();

askProgress是:

$http.get('/myweb/services/progress').success(function(response, status, headers, config){
        console.log(response);
        $scope.reportProgress = response.description;

        if(response.description < 100){//description is a 0-100 value indicating progress
            ...updating status...
            $timeout(function() {$scope.askProgress();}, 1000); //calling again
        }else{
            $scope.reportProgressL = "Done!";
        }
    }).error(function(err, status, headers, config){
        alert('Error: '+err+" "+status);
    });

我的问题是第一次调用askProgress是在服务返回状态&#34; pending&#34;之前进行的。导致不一致的进展值。 我希望在服务给我第一个&#34;待定&#34之后立即调用askProgress函数... ...是否可能?

1 个答案:

答案 0 :(得分:1)

我不确定我是否完全了解您的问题,但听起来您需要在第一个http请求返回后调用askProgress()函数。如果是,您是否尝试将通话置于then()通话中?

$http
    .get('/myweb/services/callService')
    .then(function(response, status, headers, config){
        return $scope.askProgress();
    })
    .then(function(progressResponse){

    })
    .catch(function(error){});

<强>更新

我认为您需要注册一个$http拦截器来跟踪您的请求状态。

试试这个:

DEMO

<强> app.js

var app = angular.module('plunker', []);

app.factory('myHttpInterceptor', [ function() {

    var pendingRequests = {};

    return {

      getPendingRequests: function(){
        return pendingRequests;
      },

      request: function(request) {
        console.log('*** request made @ %s ***', new Date());
        pendingRequests[request.url] = true;
        console.log('pendingRequests', pendingRequests);
        console.log('**************************');
        return request;
      },

      response: function(response) {

        console.log('*** response received @ %s ***', new Date());

        var url = response.config.url;

        if(pendingRequests.hasOwnProperty(url)){
          delete pendingRequests[url];
        }

        console.log('pendingRequests', pendingRequests);
        console.log('**************************');

        return response;
      }

    };

}]);

app.config(['$httpProvider', function($httpProvider) {

  // register our factory as an http interceptor
  // in the config phase
  $httpProvider.interceptors.push('myHttpInterceptor');

}]);

app.controller('MainCtrl', function($scope, $http, $timeout, myHttpInterceptor) {

  var targetUrl = 'big-data.json';


  $scope.callService = function(){

    console.log('*** call service ***');

    return $http.get(targetUrl)
      .then(function(){
        console.log('********** done, success **********');
      })
      .catch(function(){
        console.log('********** done, error **********'); 
      });

  }

  $scope.askProgress = function(){

    var pendingReqs = myHttpInterceptor.getPendingRequests();


    // the request in this demo is very quick
    // so I have had to change the time between checks
    // you will probably want to change this for your
    // own app
    return $timeout(1)
      .then(function(){

        if(pendingReqs.hasOwnProperty(targetUrl)){
          console.log('*** stil pending ***');
          return $scope.askProgress();
        }
        console.log('*** no pending requests ***');
        $timeout.cancel();

      })

  }

  $scope.callService();  
  $scope.askProgress(); 


});