【问题标题】:$interval making $http call, which promise is returned for chaining?$interval 进行 $http 调用,返回哪个 promise 进行链接?
【发布时间】:2014-07-07 19:47:34
【问题描述】:

我有一个角度服务和一个控制器进行交互。该服务使用 $interval 轮询服务器。我知道这会返回一个 Promise,但是它使用 $http 来调用服务器,该服务器也返回一个 Promise,并且 Promise 的链接并没有像我期望的那样发生。

服务

(function () {
    'use strict';

    var serviceId = "notificationService";

    angular.module('app').factory(serviceId, ['helpersService', '$interval', '$http', function (helpersService, $interval, $http) {
        var defaultOptions = {
            url: undefined,
            interval: 1000
        };

        var myIntervalPromise = undefined;
        var displayedNotifications = [];

        function onNotificationSuccess(response) {
            //alert("in success");
            displayedNotifications.push(response.data);
            return response.data;
        }

        function onNotificationFailed(response) {
            alert("in Failure");
            throw response.data || 'An error occurred while attempting to process request';
        }


        function initializeNotificationService(configOptions) {

            var passedOptions = $.extend({}, defaultOptions, configOptions);

            if (passedOptions.url) {

                myIntervalPromise = $interval(
                    function() {
                        //console.log(passedOptions.url);

                        //return helpersService.getAjaxPromise(passedOptions);
                        //promise.then(onNotificationSuccess, onNotificationFailed);

                        $http({
                            method: 'POST',
                            url: passedOptions.url
                        }).then(onNotificationSuccess, onNotificationFailed);

                    }, passedOptions.interval);

                //alert("in initializeNotificationService");
                return myIntervalPromise;
            }
            //return myIntervalPromise;
        }

        //$scope.$on('$destroy', function() {
        //    if (angular.isDefined(myIntervalPromise)) {
        //        $interval.cancel(myIntervalPromise);
        //        myIntervalPromise = undefined;
        //    }
        //});

        return {
            // methods
            initializeNotificationService: initializeNotificationService,
            //properties
            displayedNotifications : displayedNotifications
        };
    }]);

})();

控制器

    (function () {
    'use strict';

    var controllerId = 'MessageCtrl';
    //TODO:  INVESTIGATE HAVING TO PASS $INTERVAL TO HERE TO DESTROY INTERVAL PROMISE.
    //TODO:  HAS TO BE A WAY TO MOVE THAT INTO THE SERVICE
    angular.module('app').controller(controllerId, ['notificationService', '$scope', '$interval', function (notificationService, $scope, $interval) {
        var vm = this;
        // tied to UI element
        vm.notifications = [];

        vm.initialize = function () {
            // initialize tyhe notification service here
            var intervalPromise = notificationService.initializeNotificationService({ url: 'api/userProfile/getNotifications', interval: 5000 });

            intervalPromise.then(
                    function (response) {
                        // NEVER GETS CALLED
                        var s = "";
                        //vm.notifications.push(response);
                        // alert("successful call");
                    },
                    function (response) {
                        var s = "";
                        // THIS GETS CALLED WHEN THE PROMISE IS DESTROYED
                        // response = canceled
                        //alert("failure to call");
                    },
                    function(iteration) {
                        console.log(notificationService.displayedNotifications);
                        // This gets called on every iteration of the $interval in the service
                        vm.notifications = notificationService.displayedNotifications;

                    }
                );
            // TODO:  SEE COMMENT AT TOP OF CONTROLLER
            $scope.$on('$destroy', function () {
                if (angular.isDefined(intervalPromise)) {
                    $interval.cancel(intervalPromise);
                    intervalPromise = undefined;
                }
            });
        };

        vm.alertClicked = function (alert) {
            alert.status = 'old';
        };

        // call to init the notification service here so when the controller is loaded the service is initialized
        vm.initialize();

    }]);
})();

这最终流动的方式,我会尽力在这里展示流动

1) 服务 - $interval 使用 $http 拨打电话,这两者似乎都根据文档返回了他们自己的承诺

2) CONTROLLER - 调用 intervalPromise 的 NOTIFY callack

3) SERVICE - 调用 $http 的 onNotificationSuccess 回调 我期望的事情不会发生

4) CONTROLLER - 从不调用 intervalPromise 成功回调

服务内的onNotificationSuccess处理程序中的返回response.data是否应该触发Controller中的then链?它知道每次执行 $interval 时都会返回承诺或似乎导致控制器中的通知回调被调用,所以我对链中断的位置感到困惑。

理想 $interval 调用 $http,来自 $http 的 promise 被传递给控制器 然后每次迭代都会在 $interval 成功调用时将新消息添加到服务中,然后在控制器 onsuccess 中,我可以检查服务的属性并更新 UI。我在哪里丢失了方法链?

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    控制器中的所有内容都结束了...

    (function () {
        'use strict';
    
        var controllerId = 'NotificationCtrl';
        angular.module('app').controller(controllerId, ['helpersService', '$scope', '$interval', function (helpersService, $scope, $interval) {
            var vm = this;
            var intervalPromise = undefined;
            // tied to UI element
            vm.notifications = [];
    
            function onNotificationSuccess(response) {
                //alert("in success");
                vm.notifications.push.apply(vm.notifications, response.data);
                return response.data;
            }
    
            function onNotificationFailed(response) {
                //alert("in Failure");
                throw response.data || 'An error occurred while attempting to process request';
            }
    
            vm.initialize = function () {
                intervalPromise = $interval(
                        function () {
                            var promise = helpersService.getAjaxPromise({ url: 'api/userProfile/getNotifications' });
                            promise.then(onNotificationSuccess, onNotificationFailed);
                        }, 5000);
    
                $scope.$on('$destroy', function () {
                    if (angular.isDefined(intervalPromise)) {
                        $interval.cancel(intervalPromise);
                        intervalPromise = undefined;
                    }
                });
    
            };
    
            vm.alertClicked = function (alert) {
                //alert.status = 'old';
            };
    
            // call to init the notification service here so when the controller is loaded the service is initialized
            vm.initialize();
    
        }]);
    })();
    

    【讨论】:

    • 感谢您发布最终结果。这是我为此找到的唯一可行的解​​决方案。
    【解决方案2】:

    我建议在服务之外打破$interval 的使用,并直接在您的控制器中使用它。

    所提供的服务是从服务器获取数据的能力,而间隔是获取数据的方式,这更能说明用户界面对数据检索频率的要求。

    您似乎在做的是包装$interval 服务的功能,这给您带来了麻烦。

    注意:创建快速 plnkr 后,$interval 的报告进度事件返回迭代次数(调用次数),没有其他参数。

    【讨论】:

    • 是的,但我最初是在每次迭代中更新通知的数量。但是如果你有一个像 $interval 这样返回一个承诺的服务,它仍然会用角度来回答这个问题,但是它所调用的返回一个承诺,哪个承诺链被调用或者它们是否连接
    • 这两个 promise ($interval & $http) 没有连接也没有链接
    猜你喜欢
    • 2018-05-10
    • 1970-01-01
    • 2018-06-27
    • 2016-09-21
    • 2020-09-10
    • 2016-07-04
    • 2016-07-30
    • 1970-01-01
    • 2019-05-15
    相关资源
    最近更新 更多