角异步调用 [英] Angular async calls

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

问题描述

我有一个奇怪的问题,在我的角度应用中发生的,我觉得角的async'ness是原因,但我不知道我怎么能解决这个问题。

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();
});

和随后的两个服务...

and then the two services...

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返回的数据(),除非我裹<$ C $里面soundcloud.fetch()不可用$ C>的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之外然后我得到未定义作为结果。应该在哪里$ soundcloud.set /取指为了使两个数据集(用户和的SoundCloud)被调用立即可用?

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演示

PLUNKER DEMO

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

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

要做到这一点,创建 bootstrapper.js 。您可以不受 angular.injector中启动一个模块(['NG'])访问内置的角度服务。调用(),它接受一个函数依赖,可以注射。在 urlMap 变量只是与每个各自的URL一起设置键值存储。你这个循环 urlMap 通过 angular.forEach(),然后让所有的设置一个接一个,并存储在每个设置每个各自的键沿设置变量。存储在承诺每个 $ HTTP 承诺要求阵列与 $ q.all解决它( )。当所有的承诺都得到了解决,呼叫引导()函数,它增加了一个设置价值app.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天全站免登陆