如何将服务URL数据传递给控制器​​调用的函数

时间:2015-05-27 09:25:32

标签: jquery angularjs promise angular-services

我正在尝试从URL获取一些数据,将其存储在变量中并将其返回给我的控制器。但问题是,在变量已经返回到控制器(调用该函数)之后,处理来自URL的数据。我在 Service.js 中调用服务网址 我是这样做的:

var demoService = angular.module('demoService', []).service('myService', function($http, $q) {
    var gaugeData = {
        maxValue: 5000,
        animationSpeed: 100,
        val: 5000
    };

    console.log(gaugeData);

    var deferred = $q.defer();
    $http.get('http://myurl').then(function(data) {
        console.log(data.data.Tweets[3].FAVOURITE_COUNT);
        var gaugeData = {
            maxValue: 5000,
            animationSpeed: 100,
            val: data.data.Tweets[3].FAVOURITE_COUNT
        };
        deferred.resolve(gaugeData);
        console.log(gaugeData);
    });

    this.get = function() {
        deferred.promise.then(function(data) {
            console.log(data);
            gaugeData.val = data.val;
        });
        return gaugeData;
    };

    function sleep(milliseconds) {
        var start = new Date().getTime();
        for (var i = 0; i < 1e7; i++) {
            if ((new Date().getTime() - start) > milliseconds) {
                break;
            }
        }
    }

    this.list = function() {
        return gaugeData;
    };

});

控制器期望数据的形式与gaugeData对象相同,但由于gaugeData在返回值后填充了服务数据,因此控制器不显示任何对象( undefined )。控制台如下所示:

    Object {maxValue: 5000, animationSpeed: 100, val: 5000}
    controllers.js:202 $…t.l.$…w.a.$…e.$$ChildScope {$$childTail: null, $$childHead: null, $$nextSibling: null, $$watchers: null, $$listeners: Object…}   (console.log); from controller 
    app.js:15 TypeError: Cannot read property 'maxValue' of undefined (since an empty value is passed)
       1566
   services.js:137 Object {maxValue: 5000, animationSpeed: 100, val: 1566}
   services.js:144 Object {maxValue: 5000, animationSpeed: 100, val: 1566}

显然,控件首先进入服务,然后在处理URL时,控件跳转到控件并获取一个空值,在此之后,URL被处理并且gaugeData被值填充来自服务URL。 我试着这样做,没有承诺,推迟了。我只是使用了$http.get(url).success(function(){code});

如何将我的URL数据传递给变量并在正确的时间将其正确传递给控制器​​?

此处还有我的控制器代码片段,我正在调用服务函数:

console.log($scope);
return $scope.gaugeHome ={
         gaugeData:
             myService.get(), .....

1 个答案:

答案 0 :(得分:1)

  1. 不要将现有的承诺包含在新的延期中;这是一种反模式。 $http已经返回了一个承诺,您可以通过return来自then处理程序的新承诺或值来修改承诺。

  2. 您无法返回同步值,该值是异步操作的结果。这是一个基本矛盾。如果你需要返回最终会被设置为值的东西,那就是承诺的全部要点。您的服务应返回一个承诺,然后您的控制器将致电then

  3. 您的sleep功能令人担忧。看起来你正在使用繁忙的循环以便...做什么?挂CPU一段时间?为什么?为什么不只是$timeout

  4. 这是您的服务版本,A)获取资源一次,B)将其存储在承诺中,C)让消费者(控制者)要求承诺。然后,控制器必须调用then来决定如何处理结果。

    如果您希望您的服务能够更新资源,您可以将promise生成包装在一个再次运行fetch并返回新promise的函数中。然而,目前还不完全清楚你的最终目标是什么,所以我没有表现出这种方法。

    var demoService = angular.module('demoService', []).service('myService', function($http, $q) {
    
        var gaugePromise = $http.get('http://myurl').then(function(response) {
            var updatedGuageData = {
                maxValue: 5000,
                animationSpeed: 100,
                val: response.data.Tweets[3].FAVOURITE_COUNT
            };
            return updatedGuageData;
        });
    
        this.get = function() {
            return gaugePromise;
        };
    
    });
    

    现在,您可以让服务将值缓存为同步对象(沿着您尝试的行),并且每当异步获取它时,更新缓存作为副作用(就像你在做的那样)。但是,每当你进行异步更新时,你才知道它成功(或失败)的唯一一次是使用回调或承诺处理程序,这使得缓存的同步值毫无意义 - 为什么不只是使用结果async直接?更简单。