【问题标题】:AngularJS - Bypass the $http promises object managmentAngularJS - 绕过 $http 承诺对象管理
【发布时间】:2015-01-29 14:24:43
【问题描述】:

我有这样的服务:

angular.module('module')
.factory('UserList', function ($http) {
    return {
        getUserList: $http.get('/portal-services/NemesysPortalBackend/rest/user/all')
    };
 });

这个约束我去做

UserList.getUserList.then(function(res){$scope.data = res.data;})

在我需要它的每个控制器中。 有什么方法可以“掩盖”它以简单地拥有

$scope.data = UserList.getUserList();

谢谢

【问题讨论】:

  • 之所以必须这样调用它是因为调用是异步进行的。即使可以,我认为您也不想将其破解为阻塞的东西。
  • $http 用于在直接分配给 $scope 对象时允许“解包”承诺,但在 1.3 中已删除。如果你使用$resource,你仍然可以做你想做的事。

标签: angularjs rest angularjs-service


【解决方案1】:

我在这里假设用户列表不会经常更改,因此您可以通过这种方式将其缓存到变量中...否则每次您希望列表更改时都需要进行调用(或使用间隔重新加载列表?)

在真正需要之前获取数据称为“急切加载”

angular.module('module').factory('UserList', function ($http, $q, $interval) { // import $q as well
    var userList = []; // initialized as blank array

    var refreshList = function(){
        var deferred = $q.defer();

        $http.get('/portal-services/NemesysPortalBackend/rest/user/all').then(
            function(successResponse){
                userList = successResponse.data;
                deferred.resolve(successResponse);
            },function(failureResponse){
                // do something on error?
                deferred.reject(failureResponse);
            });

        return deferred.promise;
    } 
    refreshList(); // eager load, run right away

    // i don't recommend this next line, there are better ways of doing this
    $interval(refreshList(), 1000*60); // get new list every 60 seconds


    return {
        getUserList: function(){ return userList; }, // return user list only
        refreshList: function(){ refreshList(); } // return promise which getting new list
    };
 });

同样,我不建议使用 $interval 重新加载列表,而是在对用户列表进行更新时调用 refreshList

例如:

angular.module('module').controller('userCtrl', function(UserList) { 
    $scope.data = UserList.getUserList();

    // once you change the user list, call a refresh
    UserList.addUser().then(UserList.refreshList()).then(function(){
         $scope.data = UserList.getUserList();
    );



});

【讨论】:

    【解决方案2】:

    您不能这样做,因为 JavaScript 是单线程的。这意味着,当您使用一些异步调用时,您永远无法使其同步。 Javascript 中没有等待(*)。您不能阻止您的函数调用以等待来自服务器的结果。

    即使你这么努力:

    function getResult() {
       var result;
       UserList.getUserList.then(function(res) {
           result = res.data; // this should break the loop below
       });
       while (!result) {}; // active waiting, wasting CPU cycles
       return result;
    }
    

    ...它不起作用,因为在当前运行的代码(即无限循环)完成之前不会执行回调函数。像这样的无限循环会永远冻结整个应用程序。


    (*) 这并不意味着您不能安排函数在以后的某个时间被调用。 Promise 和闭包对此有很大帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-05
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 2017-01-20
      相关资源
      最近更新 更多