卡在无限重复的摘要循环中

Stuck with infinitely repeating digest loops

我有一个 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 秒 运行)。

这是第一个垂直条带。并不是所有的看起来都和这个完全一样,但是 completeOutstandingRequest、timeout 和 Browser.self.defer 方法总是存在的。 searchDisable 和 log 方法是我们的​​,日志是我上面说的那个。 这是另一个用于比较的,但这略有不同 - 它有另一个浏览器方法:self.url。我不确定它的作用。

以下是我发现的一些可能相关的问题:

Timeout callback can occur in the middle of a digest cycle in Firefox
$browser.defer ends up triggering changeDetection in zonejs through settimeout

P.S。我认为当我们在代码中添加一些拦截器以执行一些自动重定向时,这个问题首先开始了 - 例如当会话超时并且用户单击某些内容时,他会自动返回到登录页面重新登录。

这是拦截器:

        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);

此问题已解决。

事实证明,在任何 Unauthorized 请求的情况下,上面第 11 行返回的承诺将永远挂起,因为没有调用 .resolve().reject()deferred 对象中。

结果,加载栏的拦截器被阻止了。

我最终完全删除了自定义承诺并解决了问题。