【问题标题】:recursive http request javascript递归http请求javascript
【发布时间】:2014-06-27 17:38:52
【问题描述】:

我正在使用 AngularJS 制作单页应用程序。我想不断地向服务器发送一个待处理的 http 请求,所以一旦服务器响应,就发送另一个 http 请求。我写了递归函数 stateCheck(),但我的代码卡在函数内部,永远不会返回工厂,也永远不会更新视图。

如何让这些 http 请求在我的应用程序中不断挂起,而不会陷入无限循环?

define([
    'angular',
    'app',
    'angularRoute',
    ], function (angular, app) {
        'use strict';

        app.config(function ( $httpProvider) {        
            /* Angular automatically adds this header to the request,
               preventing us from being able to make requests to the server on another port */
            delete $httpProvider.defaults.headers.common['X-Requested-With'];
        }).factory('equipmentService', ['$http', '$rootScope', function($http, $rootScope) {
            var factory = {
                getEquipmentState: $http.get($rootScope.backendServer+'/equipment/state'),
                setEquipmentState: function(state){
                    this.equipmentState = state.state;
                    console.log('equipment state', this.equipmentState);
                    redirectState(this.equipmentState);
                }
            }
            var redirectState = function (state) {
                switch(state) {
                    case 'Active':
                        $location.path('/active');
                        break;
                    case 'Review':
                        $location.path('/review');
                        break;
                    default:
                        // don't change views
                }
            }

            function stateCheck () {
                factory.getEquipmentState
                .then(function (data) {
                    factory.setEquipmentState(data.data);
                })
                .then(stateCheck);
            }

            stateCheck();

            return factory;
        }]);
});

【问题讨论】:

    标签: javascript angularjs http recursion


    【解决方案1】:

    问题在于您初始化factory.getEquipmentState 的方式。根据定义,初始化本身已经在调用 /GET 请求,因此在您的 stateCheck() 中访问已解析的 Promise 会确认第一次调用,但不会确认下一次调用。

    要解决此问题,您可以将equipmentService 构造成如下形式:

     factory('equipmentService', ['$http', '$rootScope', 
        function($http, $rootScope) {
           var factory = {
              getEquipmentState: function() {
                 return this.equipmentState;
              },
    
              setEquipmentState: function(state){
                 this.equipmentState = state.state;
                 console.log('equipment state', this.equipmentState);
                 redirectState(this.equipmentState);
              }
           };
    
           var redirectState = function (state) {
              switch(state) {
                 case 'Active':
                    $location.path('/active');
                    break;
                 case 'Review':
                    $location.path('/review');
                 break;
                 default:
                    // don't change views
              }
           };
    
           function stateCheck () {
               $http.get($rootScope.backendServer+'/equipment/state')
                   .success(function (data) {
                       factory.setEquipmentState(data.data);
                   })
                   .then(stateCheck);
            }
    
            stateCheck();
    
            return factory;
        }])
    

    【讨论】:

    • 谢谢!我没有意识到它会重用已解决的承诺。关于如何对这部分进行单元测试的任何建议?我一直在用 jasmine 使用 httpbackend,但它总是会出现错误:意外请求,因为会有无限数量的 http 请求。
    【解决方案2】:

    问题:

    你的代码不起作用,因为你总是使用同一个 promise 对象:

    $http.get($rootScope.backendServer+'/equipment/state') 已经返回了一个 promise,并且只会被解析一次。

    解决办法:

    只保存参数正确的函数,所以换行

    getEquipmentState: $http.get($rootScope.backendServer+'/equipment/state'),
    

    getEquipmentState: $http.get.bind($http, $rootScope.backendServer+'/equipment/state'),
    


    stateCheck 中调用此函数。这意味着替换行

    factory.getEquipmentState
    

    用这一行:

    factory.getEquipmentState()
    


    这是working example

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      • 2017-11-28
      • 1970-01-01
      • 2019-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多