角度异步调用 [英] Angular async calls

查看:40
本文介绍了角度异步调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Angular 应用程序中发生了一个奇怪的问题,我认为原因是 Angular 的异步性,但我不确定如何解决它.

I have a bizarre issue happening in my Angular app and I think the async'ness of Angular is the cause but I'm not sure how I can fix it.

.run 我有以下内容:

app.run(function ($user, $soundcloud) {
    $user.set();
    $soundcloud.set();
});

然后是两个服务...

app.service('$user', ['$http',  function ($http) {    
    var currentUser;    
    this.set = function () {
        $http.get('/users/active/profile')
            .success(function (obj) {
                currentUser = obj;
            })
            .error(function () {
                console.log('ERR');
            })
    }    
    this.fetch = function () {
        return currentUser;
    }

}]);    
app.service('$soundcloud', ['$http', function ($http) {    
    var sc;    
    this.set = function () {
        $http.get('/users/active/services/soundcloud')
            .success(function (obj) {
                sc = obj;
            })
            .error(function () {
                console.log('Error fetching soundcloud feed')
            })
    }    
    this.fetch = function () {
        return sc;
    }    
}]);

<小时>

我遇到的问题是,当我转到/profile 并重新加载页面时,除非我将 $soundcloud.fetch() 包装在 中,否则从 $soundcloud.fetch() 返回的数据不可用setTimeout() 函数显然不理想,所以我想知道我应该将 $soundcloud.set() 放在哪里,以便在页面加载时立即提供这些数据.


The issue I'm having is that when I go to /profile and reload the page, the data returned from $soundcloud.fetch() isn't available unless I wrap $soundcloud.fetch() inside a setTimeout() function which obviously isn't ideal so I'm wondering where I should place $soundcloud.set() to also make that data available immediately on page load.

这是我目前的控制器:

app.controller('profileController', ['$scope', '$user', '$soundcloud', function ($scope, $user, $soundcloud) {

    $scope.activeUser = $user.fetch();
    $scope.activeSoundcloud = $soundcloud.fetch();

    console.log($user.fetch());
    setTimeout(function () {
        console.log($soundcloud.fetch());
    },100);
}]);

如果我将 $soundcloud.fetch() 放在 setTimeout 之外,那么我会得到 undefined 作为结果.应该在何处调用 $soundcloud.set/fetch 以使两组数据(用户和声音云)立即可用?

If I take $soundcloud.fetch() outside of the setTimeout then I get undefined as the result. Where should $soundcloud.set/fetch be called in order to make both sets of data (user and soundcloud) immediately available?

推荐答案

PLUNKER DEMO

解决这个问题的一种方法是获取所有必要的数据,然后手动引导应用程序.

One way to solve this problem is to fetch all the necessary data and then manually bootstrap the application.

为此,创建bootstrapper.js.您可以访问内置的 angular 服务,而无需通过 angular.injector(['ng']).invoke() 引导模块,它接受一个可以注入依赖项的函数.urlMap 变量只是设置的键值存储及其各自的 url.您通过 angular.forEach() 循环这个 urlMap,然后一个一个地获取所有设置,并将每个设置与每个设置一起存储在 settings 变量中其各自的键.将每个 $http 承诺请求存储在 promises 数组中,以使用 $q.all() 解决它.当所有 promise 都得到解决后,调用 bootstrap() 函数,该函数在 app.settings 模块中添加一个 Settings 值,然后手动引导应用程序.

To do this, create bootstrapper.js. You can access the built-in angular services without bootstrapping a module by angular.injector(['ng']).invoke() which accepts a function with dependencies that can be injected. The urlMap variable is simply a key value store for the settings together with each of its respective urls. You loop this urlMap via angular.forEach() and then get all settings one by one and store each settings in a settings variable along with each of its respective keys. Store each $http promise request in promises array to resolve it with $q.all(). When all promises have been resolved, call bootstrap() function which adds a Settings value in app.settings module and then manually bootstraps the application.

bootstrapper.js

angular.injector(['ng']).invoke(function($http, $q) {

  var urlMap = {
    $user: '/users/active/profile',
    $soundcloud: '/users/active/services/soundcloud'
  };

  var settings = {};

  var promises = [];

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

  angular.forEach(urlMap, function(url, key) {
    promises.push($http.get(url).success(function(data) {
      settings[key] = data;
    }));
  });

  $q.all(promises).then(function() {
    bootstrap(settings);
  }).catch(function() {
    bootstrap();
  });

  function bootstrap(settings) {
    appConfig.value('Settings', settings);

    angular.element(document).ready(function() {
      angular.bootstrap(document, ['app', 'app.settings']);
    });
  }

});

app.js

angular.module('app', [])

  .run(function(Settings) {
    if(Settings === null) {
      // go to login page or
      // a page that will display an
      // error if any of the requested
      // settings failed
    }
  })

  .controller('ProfileController', function($scope, Settings) {
    console.log(Settings);
  });

这篇关于角度异步调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆