【问题标题】:Why promise doesnt work as expected in AngularJS为什么 Promise 在 AngularJS 中不能按预期工作
【发布时间】:2014-02-26 21:05:37
【问题描述】:

在我的 AngularJS 应用程序中,每次请求更改我运行的页面:

    $rootScope.$on('$locationChangeStart', function (event, next, current) {
        var user;
        $http.get('/api/Authentication/UserAuthenticated').then(function (data) {
        console.log("call");
         user = data.data;
       });   
      console.log("end of call");
    });

当我运行应用程序并测试正在发生的事情时,我在控制台中看到“通话结束”在console.log("call"); 之前返回,这意味着未设置用户。这意味着如果我想检查用户是否在更改路由时登录用户将是未定义的。

我如何让 Angular 运行-> http 请求,然后才能继续?

【问题讨论】:

  • 这与promises 无关,而是$http 进行异步调用。由于get 调用是异步的,所以"end of call" 总是首先出现。
  • 对于此类任务,您应该使用路由配置的resolve 属性。
  • 你能举个例子说明我如何用resolve实现它吗?我可以看到我解决的文档会让 rute 等到所有 http 请求都完成
  • 请查看我的回答。

标签: angularjs angularjs-http


【解决方案1】:

我有点误解了这个问题。您可以让$routeProvider 解决$http 承诺:

var app = angular.module("myApp");

app.config(["$routeProvider", function($routeProvider) {
  $routeProvider.when("/",{
    templateUrl: "myTemplate.html",
    controller: "MyCtrl",
    resolve: {
      user: ["$http", "$q", function($http, $q) {
        var deferred = $q.defer();
        $http.get('/api/Authentication/UserAuthenticated').success(function(data){
           deferred.resolve(data.data);
        }).error(function(error) {
           deferred.resolve(false);
        });
        return deferred.promise;
      }]
    }
  });
}]);

如果获取用户数据的代码过于复杂,您可以为其创建一个服务,并将该服务注入到$routeProviderresolve 函数中。

在您的控制器中,您只需注入承诺(将被解决):

app.controller("MyCtrl",["$scope","user", function($scope, user) {
   if (!user) {
      alert("User not found");
   }
...
}]);

【讨论】:

  • $scope.user = data.data;将设置为延迟,因此位置更改将在 http 得到响应之前通过。
  • 最后一个问题,当我改变位置时,如何在我的路线上选择用户参数?在 onlocationChangestart 中?
  • “用户参数”是什么意思。 $http 请求是否需要通过输入表单填写的用户 ID 字符串(例如“12345”)?
  • 我只想在用户为假时显示一条弹出消息,我尝试在 $locationChangeStart 中检查它,但我无法从 $route 中获取用户参数
  • 我已经稍微更新了我的答案。您会在错误块中注意到resolve(false)。在您的控制器中,您会得到false 对应的user。当然,您需要改进这一点。
【解决方案2】:

使用async:false。它对我有用

试试这个代码,而不是你的代码

$rootScope.$on('$locationChangeStart', function (event, next, current) {
$http({method: 'GET',
            url: '/api/Authentication/UserAuthenticated',                
            async: false
              }).success(function (data) {
            console.log("call");
            user = data.data;
             }
         console.log("end of call");   
 });

【讨论】:

  • 我没有投票给你,但我怀疑这是因为你使用“hacky”解决方案来规避正常行为。
猜你喜欢
  • 2021-05-30
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多