当前位置: 首页 > 知识库问答 >
问题:

当运行块中存在无限循环时,工厂中的$HTTP成功回调不运行

袁谭三
2023-03-14

下面是我的代码,相关部分加粗:

授权.js

 angular
      .module('mean-starter')
      .run(run);

    function run($rootScope, Auth, $state) {
      $rootScope.$on('$stateChangeStart', function(event, toState, toParams) {
        if (typeof toState.authenticate !== 'undefined') {
          var currentUser = Auth.getCurrentUser();
          while (!currentUser._id) {}
          var isAdmin = currentUser.role === 'admin';
          var isAuthorized = currentUser._id.toString() === toParams.id;
          if (!Auth.isLoggedIn()) {
            event.preventDefault();
            alert('Must be logged in to access this route.');
            $state.go('login');
          }
          else if (toState.authenticate.authorized) {
            if (!isAdmin && !isAuthorized) {
              event.preventDefault();
              alert('You are not authorized to access that route.');
            }
          }
          else if (toState.authenticate.isAdmin) {
            if (!isAdmin) {
              event.preventDefault();
              alert('You must be an admin to access this route.');
            }
          }
        }
      });
    }

auth.factory.js

angular
  .module('mean-starter')
  .factory('Auth', function($http, $state, $window, $cookies) {
    console.log('factory cb');
    var currentUser = {};
    if ($cookies.get('userId')) {
      console.log('userId');
      $http
        .get('/current-user')
        .success(function(data) {
          console.log('success');
          angular.copy(data, currentUser);
        })
        .error(function() {
          console.log('Problem getting the current user.');
        });
    }

    return {
      signup: function(user) {
        return $http.post('/users', user)
                  .success(function(data, status, headers, config) {
                    angular.copy(data, currentUser);
                    $cookies.put('userId', data._id);
                    $window.location.href = '/';
                  });
      },
      login: function(user) {
        return $http
                  .post('/login', user)
                  .success(function(data) {
                    angular.copy(data, currentUser);
                    $cookies.put('userId', data._id);
                    $window.location.href = '/';
                  });
      },
      logout: function() {
        $http
          .get('/logout')
          .success(function() {
            angular.copy({}, currentUser);
            $cookies.remove('userId');
            $window.location.href = '/';
          })
          .error(function() {
            console.log('Problem logging out.');
          });
      },
      getCurrentUser: function() {
        return currentUser;
      },
      isLoggedIn: function() {
        return !!currentUser._id;
      }
    };
  });

我的问题是,如果没有while循环,我会得到以下错误:

Cannot read property 'toString' of undefined

它指的是currentuser._idundefined,而我试图对其调用ToString。我的理解是,auth.getCurrentUser()最初返回对{}的引用。然后赋值语句将{}分配给CurrentUser,代码继续执行。当响应返回时,它应该更新{},因此应该“更新”CurrentUser,因为CurrentUser指向更新的对象。

如果这是真的,我的问题就可以理解了,因为它试图在响应返回之前执行currentuser._id.toString()。因此,我尝试将while循环放入其中,以暂停执行,直到响应返回。但是while循环正在无限地运行!响应是否应该最终返回,更新CurrentUser,当它返回时,!CurrentUser._ID应该是false,并且循环应该中断?

首先注销工厂CB。则userid将注销。到目前为止还不错。但随后无限循环启动,success永远无法注销。请求不是应该是异步的吗?while循环如何阻止它?这是怎么回事?

电话没有问题。如果没有while循环,它将命中success回调并记录success。此外,如果authorization.js中的Iconsole.dir(currentUser)给出了用户,但如果Iconsole.log(currentUser),则给出了一个空对象。不知道为什么。

共有2个答案

裴泰平
2023-03-14

似乎正在发生的是,您的身份验证内容正在被异步检查(这是有意义的,因为它必须执行HTTP调用,而这不是即时的)

因此,在运行脚本时,auth.getCurrentUser()的结果,即CurrentUser对象,没有填充您试图访问的数据,因为它是在这一行写入的:

angular.copy(data, currentUser);

它确实在一个异步块内。所以现在的情况是,_id可能还不是CurrentUser上的属性,所以实际上是在Undefined上调用ToString()

您的解决方案可能是使用回调或承诺。如果您是auth.factory.js的作者,那么您可能会考虑做的是在GetCurrentUser中同步返回对象,而不是返回一个承诺或回调,当HTTP请求完成时,它就会实现。

编辑:这也是脚本中的console.dir不会返回任何内容的原因,因为在它运行时,它不会填充任何数据。

龙学
2023-03-14

AFAIK,由于Javascript是单线程的,当线程在while循环中旋转时,http回调将得不到CPU时间来处理响应。

 类似资料:
  • 问题内容: 我希望代码在后台运行并定期更新我的GUI。我该怎么做? 例如,假设我想在GUI代码的背景中执行以下操作,如下所示: 这是GUI代码: 问题答案: 尚不清楚顶部的代码应该做什么,但是,如果只想每秒(或每秒钟)调用一个函数,则可以使用该方法。 因此,如果您只想使用进行操作,则可能需要执行以下操作: 您可以将此函数作为您类的方法(在本例中称为),您的代码将如下所示:

  • 我正在做简单的Spring批量工作。当我启动作业时,它在无限循环中运行。它不会停止。根据我的时间表,它应该每10秒运行一次。但当工作开始时,它不会停止。它只是分别从读卡器、处理器和写入器打印系统输出。我正在为读者、处理者和作者创造工作机会。我正在按注释进行所有配置。不是通过xml。 下面是批处理配置 PersonReader。JAVA 人Writer.java 个人处理器。JAVA

  • 我知道这在StackOverflow上被问过很多次,但我尝试过很多不同的解决方案,没有一个奏效。所以我决定问问社区该怎么做。下面是我的代码中的相关片段。 请注意,这只是我的代码中从控制台输入的部分,不包含任何其他内容。我有其他东西设置,要求代码是这种格式。 将Input.HasNext()替换为Input.HasNextLine() 将input.hasnext()替换为input.next()!

  • 我是Tomcat/tech新手,所以如果我在问题描述中犯了任何错误,我很抱歉。 我读过很多关于相关主题的帖子,但由于我已经运行了一个应用程序十年,突然出现这个问题对我来说真的很奇怪。此外,这个环境就像一个测试服务器,目前我是唯一一个使用它的仪表板。因此,系统负载增加的可能性似乎不对;也没有内存泄漏的可能性。 有人能告诉我在这种情况下可能出了什么问题吗? 谢了! 编辑:我认为我的问题是不同的,因为它

  • 问题内容: 当我在 while循环中 使用 try和catch 块时,我的程序有一个无限 循环 。 当我输入一个整数时,它运行良好并要求另一个输入,但是当我输入一个字符时,它将进入无穷循环。为什么会这样呢? 问题答案: 遇到无效输入时,由于nextInt()不使用无效令牌,因此程序进入无限循环。因此,导致该异常的任何令牌都将保留在该位置,并在下次尝试使用nextInt()时继续引发异常。 可以通过

  • 不知道如何阻止这个while循环无限重复。我使用检查用户输入是否为int。如果没有输入int值,则循环将无限重复。