AngularJS $timeout в фабрике ресурсов

В настоящее время у меня есть угловое приложение, которое при входе пользователя в систему вызывает службу, чтобы начать вызов сервера для обновления счетчика, разрешая возврат на стороне сервера только в том случае, если пользователь аутентифицирован.

resource.approvalsCount = 0;
var approvalsCountTimer;
resource.getApprovalsCount = function (username) {
    return resource.query({
        username: username,
        q: 'approvalsCount'
    }).$then(function (response) {
        resource.approvalsCount = response.data.count;
        approvalsCountTimer = $timeout(resource.getApprovalsCount, 3000);
        return resource.approvalsCount;
    });
};

Когда пользователь выходит из системы, я пытаюсь отменить этот счетчик, иначе сервер вернет несанкционированную ошибку 401, вызвав функцию на основе ресурса:

resource.cancelTimers = function () {
    $timeout.cancel(approvalsCountTimer);
}

Проблема в том, что счетчик продолжает работать даже после того, как я вызываю отмену по истечении времени ожидания $, которое возвращает 401 с сервера. Выход из консоли возвращает, функция отмены возвращает true (отмена сработала). Я пробовал несколько разных мест начала $timeout безрезультатно, есть ли способ убедиться, что все $timeouts отменены? Я не понимаю, чего мне не хватает в этой конфигурации.

ИЗМЕНИТЬ

angular.module('resources.approvals.approvals', ['ngResource'])
    .factory('Approvals', ['$timeout', '$resource', function ($timeout, $resource) {
    var resource = $resource('/approvals/:username/:requestID', {}, {
        'update': {
            method: 'PUT'
        }
    });
    resource.approvalsCount = 0;
    var approvalsCountTimer;
    resource.getApprovalsCount = function (username) {
        return resource.query({
            username: username,
            q: 'approvalsCount'
        }).$then(function (response) {
            resource.approvalsCount = response.data.count;
            approvalsCountTimer = $timeout(resource.getApprovalsCount, 3000);
            return resource.approvalsCount;
        });
    };
    resource.cancelTimers = function () {
        $timeout.cancel(approvalsCountTimer);
    };
    return resource;
}]);

person Brian    schedule 08.08.2013    source источник
comment
Как вы вызвали cancelTimers в своем коде?   -  person zs2020    schedule 08.08.2013
comment
Я вызываю его в процессе выхода из системы, поэтому в моем контроллере главного меню у меня есть $scope.logout = function(){ Resource.cancelTimers(); }   -  person Brian    schedule 08.08.2013
comment
Определен лиapplicationsCountTimer при закрытии объекта ресурса? Можете ли вы опубликовать весь код ресурса?   -  person zs2020    schedule 08.08.2013
comment
Добавлены изменения кода выше.   -  person Brian    schedule 08.08.2013
comment
вы на самом деле рекурсивно вызываете getApprovalsCount в тайм-ауте, это то, что вам действительно нужно?   -  person zs2020    schedule 08.08.2013
comment
Я так думаю? Я хочу, чтобы таймер постоянно вызывал сам себя для обновления с сервера при входе в систему, а при выходе из системы останавливал таймер. Если есть лучший способ сделать это, я полностью за него, я просто подумал, что это сработает лучше всего.   -  person Brian    schedule 08.08.2013
comment
Похоже, что если я отменяю после того, как один таймер был создан и находится в процессе завершения своего обратного вызова, то он не может отменить этот таймер, и когда он возвращает свое значение с сервера, он возвращается без аутентификации. Не уверен, как это решить, но в этом подходе было полезно сделать немного больше ведения журнала на основе приведенного ниже примера.   -  person Brian    schedule 08.08.2013


Ответы (1)


Я думаю, что ваш код выглядит хорошо. Это должно быть что-то другое.

Я немного упростил, и вы можете увидеть это в демо. он имитирует http-вызов каждые полсекунды, а cancelTimes будет вызываться через 4 секунды.

app = angular.module('app', []);
app.factory('Approvals', ['$timeout', function ($timeout) {
    var resource = {};
    resource.approvalsCount = 0;
    var approvalsCountTimer;
    resource.getApprovalsCount = function (username) {
        console.log(approvalsCountTimer);
        approvalsCountTimer = $timeout(resource.getApprovalsCount, 500);
    };
    resource.cancelTimers = function () {
        console.log("stopped");
        $timeout.cancel(approvalsCountTimer);
    };
    return resource;
}]);

function Ctrl($scope, $timeout, Approvals) {
    Approvals.getApprovalsCount();
    $timeout(Approvals.cancelTimers, 4000)
}
person zs2020    schedule 08.08.2013