Застрял с бесконечно повторяющимися циклами дайджеста

У меня есть Angular SPA, на котором я работаю с Angular Loading Bar и AngularJS v1.4.9.

В течение некоторого времени это происходило так, что после загрузки приложения панель застревала через некоторое время, указывая, что не все запросы выполняются. Кроме того, один из console.log()s Я в нашем коде стрелял непрерывно, примерно 1-2 раза в секунду. Панель завершается, и console.log работает нормально, когда пользователь перезагружает страницу (но не останавливается самостоятельно).

console.log() устанавливается внутри функции, прикрепленной к ng-disabled директива, так что я знаю, что это индикатор выполнения цикла дайджеста.

Я использую Chrome в качестве браузера и недавно выполнил профилирование. Вот несколько скриншотов того, что я вижу: С высоты птичьего полета

Это широкий взгляд. Как показано здесь, сначала это происходит в 100 мс, затем в 400, затем в 600 и т. Д. (Я выполнил 3 с).

полоса 1 Это самая первая вертикальная полоса. Не все из них выглядят точно так же, как этот, но методы completeOutstandingRequest, timeout и Browser.self.defer всегда присутствуют. Методы searchDisable и log - наши, журнал - тот, о котором я говорил выше. self.url Вот еще один для сравнения, но это немного отличается - у него есть другой метод браузера: self.url. Я не уверен, что это делает.

Вот некоторые проблемы, которые я нашел, которые могут быть связаны:

Обратный вызов тайм-аута может происходить в середине цикла дайджеста в Firefox
$ browser.defer заканчивает тем, что запускает changeDetection в zonejs через settimeout

PS Я думаю, что эта проблема впервые возникла, когда мы добавили несколько перехватчиков в наш код для выполнения некоторых автоматических перенаправлений - например, когда время сеанса истекло, и пользователь что-то нажимает, он автоматически возвращается на страницу входа для повторной регистрации.

Это перехватчик:

        interceptor.$inject = ['$rootScope', '$q'];
        function interceptor($rootScope, $q) {
            return {
                responseError: function (rejection) {
                    var config = rejection.config || {};
                    if (!config.ignoreAuthModule) {
                        switch (rejection.status) {
                            case 401:
                                var deferred = $q.defer();
                                $rootScope.$broadcast('event:auth-loginRequired', rejection);
                                return deferred.promise;
                            case 403:
                                $rootScope.$broadcast('event:auth-forbidden', rejection);
                                break;
                        }
                    }
                    return $q.reject(rejection);
                }
            };
        }

        $httpProvider.interceptors.push(interceptor);

1 ответ

Решение

Эта проблема была решена.

Оказывается, что в случае любого Unauthorized запросы, обещание, которое возвращается в строке 11 выше, оставалось в ожидании навсегда, потому что не было вызова .resolve() или же .reject() в deferred объект.

В результате перехватчик загрузочного бруса был заблокирован.

Я полностью удалил пользовательское обещание, и это решило проблему.

Другие вопросы по тегам