如何在不使用promises的情况下跨多个控制器访问工厂中的异步数据

时间:2014-04-28 16:19:11

标签: javascript angularjs

我试图将一些用户数据存储在可以在不同控制器上访问和修改的服务中,并且数据最初将通过$ http调用来提取。由于必须加载数据,我在之前的代码中使用了promises,但写入这可能会非常恼人。例如,即使是基本的getter函数也必须写成如下

UserData.getData().then(function(data) {
    //do something with the data
})

其中UserData.getData()始终通过deferred.promise返回一个承诺(如果已经提取了数据,则立即解决)。我想知道是否有分裂a)$ http调用,以及b)getter和setter方法分成两个不同的服务,这样如果我从b)调用getter和setter方法,我就不需要用then包裹所有内容?

例如,我试图让UserFactory负责$ http调用,而UserData负责getter和setter。但是,我无法让代码工作,因为UserData.getData()将返回undefined,并想知道是否有人可以提供帮助? (我真的不想在任何地方使用then

angular.module('testApp', [])
//mocks a service that gets data from a server
.factory('UserFactory', function($timeout, $q) {
    return {
        getData: function() {
            var deferred = $q.defer();
            $timeout(function() {
                deferred.resolve({title: 'hello world'});
            }, 1000);
            return deferred.promise;
        }
    }
})
.factory('UserData', function(UserFactory) {
    var data;

    return {
        //if already pulled, use existing data
        getData: function() {
            if (data) return data;
            UserFactory.getData().then(function(res) {
                data = res;
                return data;
            })
        }
    }
})

http://jsfiddle.net/QNLk2/1/

1 个答案:

答案 0 :(得分:0)

then方法是异步执行的,所以返回方法没有效果。这就是为什么在数据到达之前,每次调用getData都会返回undefined。

您可以尝试以下方法,如果您希望在数据准备就绪时收到通知,或者只是等待在返回变量中填充数据,则可以指定回调。

.factory('UserData', function(UserFactory) {
    var data = {};

    return {
        getData: function(callback) {
            UserFactory.getData().then(function(res) {
                angular.extend(data, res);
                if (callback) {
                    callback(data);
                }
            });
            return data;
        }
    }
})