我可以通过电话启动投票服务吗? AngularJS

Can I start the polling service by call ? AngularJS

我已经在 AngularJS 中编写了一个轮询服务,如果我的 post 请求是 done.But 我想启动该服务,如果我调用 gui,轮询服务是活动的。

如果 post 请求完成,我已经尝试实现开始函数、结束函数并调用 start() 函数。但它不起作用:/

我的投票服务:

.factory('NotificationPollService',
['$http', '$q', '$interval',
function ($http, $q, $interval) {

    var deferred = $q.defer();
    var notification = {};

    notification.poller = $interval(function(id) {
        $http.get('http://localhost:9999/v1/jmeter/id', {cache: false})
        .success(function(data, status, headers, config) {
             return data;
        }, 10000);
    });

    notification.endPolling = function() {$interval.cancel(this.interval);};    

}])

和我 post 请求的控制器

.controller('HomeController',
['$scope', '$rootScope', 'SendJmeterFile', 'NotificationPollService',
function ($scope, $rootScope, SendJmeterFile , NotificationPollService) {

    $scope.upload = function() {

        var customArtifacts = "";
        var testDataBase = "";

        if($scope.jmeterFile.customArtifact == undefined){
            customArtifacts = null;
        } else {customArtifacts = $scope.jmeterFile.customArtifact.base64}

        if($scope.jmeterFile.testDataBase == undefined){
            testDataBase = null;
        } else {testDataBase = $scope.jmeterFile.testDataBase.base64}

        SendJmeterFile.upload($scope.jmeterFile.jmeter.base64, customArtifacts, $scope.jmeterFile.customProperties, $scope.jmeterFile.instanceConfiguration, $scope.jmeterFile.instances, $scope.jmeterFile.providerID, testDataBase)
            .then(function(data) {
                alert("Daten erfolgreich verschickt!");
                console.log(data);  
                NotificationPollService.poller(data.id)
                //.then(function(data) {
                    /*if(data.status == "SETUP")

                    if(data.status == "TEST")

                    if(data.status == "DONE")

                    if(data.status == "ERROR")
                }), function(data) {
                    })*/
            }, function(data) {
                alert("Fehler!");
                console.log(data);
            });     
    };
}])

您尝试调用 NotificationPollService.poller(data.id),实际上是 Promise,因为之前在 NotificationPollService 中您像这样分配了 notification.poller

notification.poller = $interval(function(id) {
    $http.get('http://localhost:9999/v1/jmeter/id', {cache: false})
    .success(function(data, status, headers, config) {
         return data;
    }, 10000);
});

现在您的 notification.poller$interval 函数的 return 值。 为了让它工作,你应该包装这个函数,这样你就可以实际传递一个 id 给它。

一个问题是 $interval() 在注入您的控制器后立即被调用。您实施 'Start' 方法或类似方法的预感是一个很好的预感 - 但您可能可以通过让工厂 return 一个函数来进一步简化它。然后,您可以根据需要多次在控制器中实例化该函数。

但是,还有更多的问题。一个 promise 只能被 resolve 一次,并且由于你多次执行 HTTP 请求,我的猜测是你想要 'notified' 的状态变化,直到状态被标记为 'Done'。您目前负责检查控制器的状态。但是,如果您只想收到 "error" 和 "success" 步骤的通知,那么让 Poller 服务负责解释从您的服务返回的状态信息可能会好得多,并且只依赖于控制器中的标准承诺行为。我选择展示后一种情况的示例:

更新:此处示例 plnkr:http://plnkr.co/edit/e7vqU82fqYGQuCwufPZN?p=preview

angular.module('MYMODULENAMEHERE')
.factory('NotificationPoller',
    ['$http', '$q', '$interval',
    function ($http, $q, $interval) {

        return poller;

        function poller(id) {
            var _this = this;
            var deferred = $q.defer();

            var interval = $interval(function() {
                $http
                    // I assumed you actually want to use the value of 'id' in your
                    // url here, rather than just the word 'id'.
                    .get('http://localhost:9999/v1/jmeter/' + id, {cache: false})
                    .then(function(data, status, headers, config) {
                        // I commented out the following statement. It is meaningless because
                        // you can't do anything with the return value since it's an anonymous
                        // function you're returning it from. Instead, you probably meant to 
                        // use the promise to return the data.

                        // return data;

                        if(data.status == "SETUP") {
                            deferred.notify(data);
                        }
                        else if(data.status == "TEST") {
                            deferred.notify(data);
                        }
                        else if(data.status == "DONE") {
                            _this.endPolling(); // Automatically stop polling when status is done
                            deferred.resolve(data);
                        }
                        else { // data.status == "ERROR" (or anything else that's not expected)
                            _this.endPolling(); // Automatically stop polling on error
                            deferred.reject(data);
                        }                       
                    }, function(data) {
                        _this.endPolling();
                        deferred.reject(data);
                    });
            }, 10000);

            this.endPolling = function() {
                $interval.cancel(interval);
            };

            // Make the promise available to calling code
            this.promise = deferred.promise;
        };
}])

现在您的控制器可以更轻松地使用您的轮询服务。为清楚起见,这里有一个使用轮询服务的精简控制器示例:

angular.module('MYMODULENAMEHERE')
.controller('HomeController', [
    'NotificationPoller',
    function(NotificationPoller) {

        var some_id = 207810;

        var poller = new NotificationPoller(some_id);
        poller.promise.then(onSuccess, onError, onNotify);

        function onSuccess(data) {
            // data.status == "DONE"
        };

        function onError(data) {
            // data.status == "ERROR"
        };

        function onNotify(data) {
            // data.status == "TEST" || data.status == "SETUP"
        };

    }]);

如您所见,工厂通过这种方式承担了更多的责任,但您的控制器不再需要了解后端可以发送的所有状态的详细信息。它只使用标准承诺。