source

한 페이지에 있는 총 시계 수를 어떻게 세나요?

bestscript 2023. 3. 16. 21:34

한 페이지에 있는 총 시계 수를 어떻게 세나요?

JavaScript에서 페이지 전체의 각도 시계 수를 셀 수 있는 방법이 있습니까?

우리는 바타랑을 사용하지만 항상 우리의 필요에 맞는 것은 아니다.응용 프로그램이 커서 자동 테스트를 사용하여 시계 수가 너무 많이 증가했는지 확인하고 싶습니다.

컨트롤러 단위로 시계를 세는 것도 도움이 됩니다.

편집: 제 시도는 이렇습니다.class ng-scope의 모든 것에 시계를 카운트합니다.

(function () {
    var elts = document.getElementsByClassName('ng-scope');
    var watches = [];
    var visited_ids = {};
    for (var i=0; i < elts.length; i++) {
       var scope = angular.element(elts[i]).scope();
       if (scope.$id in visited_ids) 
         continue;
       visited_ids[scope.$id] = true;
       watches.push.apply(watches, scope.$$watchers);
    }
    return watches.length;
})();

수 .body로로 합니다.html에 상관없습니다.ng-app)

(function () { 
    var root = angular.element(document.getElementsByTagName('body'));

    var watchers = [];

    var f = function (element) {
        angular.forEach(['$scope', '$isolateScope'], function (scopeProperty) { 
            if (element.data() && element.data().hasOwnProperty(scopeProperty)) {
                angular.forEach(element.data()[scopeProperty].$$watchers, function (watcher) {
                    watchers.push(watcher);
                });
            }
        });

        angular.forEach(element.children(), function (childElement) {
            f(angular.element(childElement));
        });
    };

    f(root);

    // Remove duplicate watchers
    var watchersWithoutDuplicates = [];
    angular.forEach(watchers, function(item) {
        if(watchersWithoutDuplicates.indexOf(item) < 0) {
             watchersWithoutDuplicates.push(item);
        }
    });

    console.log(watchersWithoutDuplicates.length);
})();
  • 해 준 에 이 되었습니다.$isolateScope검색 및 워쳐의 답변/답변 내용이 중복될 수 있습니다.

  • 이 Ben2307을 합니다.'body'변경이 필요할 수 있습니다.


원래의

클래스가 아닌 HTML 요소의 데이터 속성을 확인한 것 외에는 동일한 작업을 수행했습니다.여기서 검색해봤습니다.

http://fluid.ie/

그리고 83점을 받았다.난 내 것을 조사했고 121점을 받았다.

(function () { 
    var root = $(document.getElementsByTagName('body'));
    var watchers = [];

    var f = function (element) {
        if (element.data().hasOwnProperty('$scope')) {
            angular.forEach(element.data().$scope.$$watchers, function (watcher) {
                watchers.push(watcher);
            });
        }

        angular.forEach(element.children(), function (childElement) {
            f($(childElement));
        });
    };

    f(root);

    console.log(watchers.length);
})();

이것도 내 거에 넣었어

for (var i = 0; i < watchers.length; i++) {
    for (var j = 0; j < watchers.length; j++) {
        if (i !== j && watchers[i] === watchers[j]) {
            console.log('here');
        }
    }
}

아무것도 출력되지 않았기 때문에, 제 것이 더 좋다고 생각합니다(시계를 더 많이 발견했다는 점에서). 하지만, 제 것이 솔루션 세트의 적절한 서브셋이 아니라는 것을 확실히 알 수 있는 상세한 각도 지식이 부족합니다.

나는 그들이 같은 범위에 있는 시청자들을 두 배로 세기 때문에 언급된 접근법이 부정확하다고 생각한다.내 북마크릿 버전은 다음과 같습니다.

https://gist.github.com/DTFagus/3966db108a578f2eb00d

또한 관찰자를 분석하기 위한 몇 가지 세부 사항도 보여줍니다.

여기 스코프 구조를 조사하여 정리한 해답이 있습니다.효과가 있는 것 같다.이것이 얼마나 정확한지 잘 모르겠고 내부 API에 따라 다릅니다.angularjs 1.0.5를 사용하고 있습니다.

    $rootScope.countWatchers = function () {
        var q = [$rootScope], watchers = 0, scope;
        while (q.length > 0) {
            scope = q.pop();
            if (scope.$$watchers) {
                watchers += scope.$$watchers.length;
            }
            if (scope.$$childHead) {
                q.push(scope.$$childHead);
            }
            if (scope.$$nextSibling) {
                q.push(scope.$$nextSibling);
            }
        }
        window.console.log(watchers);
    };

새로운 크롬 플러그인이 있어 앱의 현재 전체 감시자와 마지막 변경 사항(+/-)을 언제든지 자동으로 표시합니다.정말 멋져요.

https://chrome.google.com/webstore/detail/angular-watchers/nlmjblobloedpmkmmckeehnbfalnjnjk

Jared의 답변과 같은 단어는 약간 개선되었습니다.

(function () {
    var root = $(document.getElementsByTagName('body'));
    var watchers = 0;

    var f = function (element) {
        if (element.data().hasOwnProperty('$scope')) {
            watchers += (element.data().$scope.$$watchers || []).length;
        }

        angular.forEach(element.children(), function (childElement) {
            f($(childElement));
        });
    };

    f(root);

    return watchers;
})();

최근 내 어플리케이션에서 많은 수의 뷰어들로 인해 어려움을 겪고 있을 때, 나는 ng-warters - https://github.com/kentcdodds/ng-stats이라는 훌륭한 도서관을 발견했다.최소한의 설정으로 현재 페이지의 감시자 수 + 다이제스트 사이클 길이를 제공합니다.또한 작은 실시간 그래프를 투영할 수도 있습니다.

AngularJS.3에서는 AngularJS 1.3.2'는countWatchersngMock을 사용합니다.

/*** @ngdoc 메서드* @name $rootScope.범위#$카운트감시자* @module ngMock* @description* 현재 스코프의 직간접 하위 스코프의 모든 워처를 카운트합니다.
** 현재 범위의 관찰자가 카운트에 포함되며 모든 관찰자도 카운트에 포함됩니다.* 아이 스코프를 격리합니다.
** @returns {number} 워치 총수.
*/
함수 count Watchers(){var root = angular.displaces(표준).injector().get('$rootScope');
var count = 루트입니다.$$squ ?root.$$syslog.length : 0; // 현재 범위 포함var pendingChildHeads = [root]입니다.$$childHead];
가변 전류 범위;
(ChildHeads.length 보류 중){currentScope = pendingChildHeads.shift();
while (현재 범위){카운트 += currentScope.$$watchers? 현재 범위.$$sec.length : 0;pendingChildHeads.push(현재 범위).$$childHead);currentScope = currentScope.$$nextSibling;}}
반환 횟수}

레퍼런스

아래 코드를 직접 가져왔습니다.$digest기능 자체입니다.셀렉터('어플리케이션 요소 셀렉터')를 document.body를 참조해 주세요를 참조해 주세요.

(function ($rootScope) {
    var watchers, length, target, next, count = 0;

    var current = target = $rootScope;

    do {
        if ((watchers = current.$$watchers)) {
            count += watchers.length;
        }

        if (!(next = (current.$$childHead ||
                (current !== target && current.$$nextSibling)))) {
            while (current !== target && !(next = current.$$nextSibling)) {
                current = current.$parent;
            }
        }
    } while ((current = next));

    return count;
})(angular.element(document.body).injector().get('$rootScope'));

사용하는 기능은 다음과 같습니다.

/**
 * @fileoverview This script provides a window.countWatchers function that
 * the number of Angular watchers in the page.
 *
 * You can do `countWatchers()` in a console to know the current number of
 * watchers.
 *
 * To display the number of watchers every 5 seconds in the console:
 *
 * setInterval(function(){console.log(countWatchers())}, 5000);
 */
(function () {

  var root = angular.element(document.getElementsByTagName('body'));

  var countWatchers_ = function(element, scopes, count) {
    var scope;
    scope = element.data().$scope;
    if (scope && !(scope.$id in scopes)) {
      scopes[scope.$id] = true;
      if (scope.$$watchers) {
        count += scope.$$watchers.length;
      }
    }
    scope = element.data().$isolateScope;
    if (scope && !(scope.$id in scopes)) {
      scopes[scope.$id] = true;
      if (scope.$$watchers) {
        count += scope.$$watchers.length;
      }
    }
    angular.forEach(element.children(), function (child) {
      count = countWatchers_(angular.element(child), scopes, count);
    });
    return count;
  };

  window.countWatchers = function() {
    return countWatchers_(root, {}, 0);
  };

})();

이 함수는 해시를 사용하여 동일한 범위를 여러 번 카운트하지 않습니다.

Lars Eidnes의 블로그(http://larseidnes.com/2014/11/05/angularjs-the-bad-parts/)에서 총 감시자 수를 수집하기 위해 게시된 재귀 함수는 다음과 같습니다.여기에 게재된 기능과 조금 높은 수치를 기록한 그의 블로그에 게재된 기능을 사용하여 결과를 비교합니다.어느 쪽이 더 정확한지 알 수 없다.교차 참조용으로 여기에 추가되었습니다.

function getScopes(root) {
    var scopes = [];
    function traverse(scope) {
        scopes.push(scope);
        if (scope.$$nextSibling)
            traverse(scope.$$nextSibling);
        if (scope.$$childHead)
            traverse(scope.$$childHead);
    }
    traverse(root);
    return scopes;
}
var rootScope = angular.element(document.querySelectorAll("[ng-app]")).scope();
var scopes = getScopes(rootScope);
var watcherLists = scopes.map(function(s) { return s.$$watchers; });
_.uniq(_.flatten(watcherLists)).length;

참고: Angular 앱에서 "ng-app"을 "data-ng-app"로 변경해야 할 수 있습니다.

Plantian의 답변이 더 빠릅니다.https://stackoverflow.com/a/18539624/258482

여기 제가 손으로 쓴 기능이 있습니다.재귀 함수를 사용할 생각은 없었지만, 대신 이렇게 했습니다.그게 더 날씬할 수도 있어, 나도 몰라.

var logScope; //put this somewhere in a global piece of code

다음으로 가장 높은 컨트롤러에 넣습니다(글로벌컨트롤러를 사용하는 경우).

$scope.$on('logScope', function () { 
    var target = $scope.$parent, current = target, next;
    var count = 0;
    var count1 = 0;
    var checks = {};
    while(count1 < 10000){ //to prevent infinite loops, just in case
        count1++;
        if(current.$$watchers)
            count += current.$$watchers.length;

        //This if...else is also to prevent infinite loops. 
        //The while loop could be set to true.
        if(!checks[current.$id]) checks[current.$id] = true;
        else { console.error('bad', current.$id, current); break; }
        if(current.$$childHead) 
            current = current.$$childHead;
        else if(current.$$nextSibling)
            current = current.$$nextSibling;
        else if(current.$parent) {
            while(!current.$$nextSibling && current.$parent) current = current.$parent;
            if(current.$$nextSibling) current = current.$$nextSibling;
            else break;
        } else break;
    }
    //sort of by accident, count1 contains the number of scopes.
    console.log('watchers', count, count1);
    console.log('globalCtrl', $scope); 
   });

logScope = function () {
    $scope.$broadcast('logScope');
};

그리고 마지막으로 서점:

javascript:logScope();

이 질문에는 조금 늦었지만, 저는 이것을 사용합니다.

angular.element(document.querySelector('[data-ng-app]')).scope().$$watchersCount

올바른 querySelector를 사용해야 합니다.

언급URL : https://stackoverflow.com/questions/18499909/how-to-count-total-number-of-watches-on-a-page