Angular“10 $ digest () 반복에 도달했습니다”오류 문제를 해결하는 방법
$ digest () 반복 10 회에 도달했습니다. 중단!
"최근 5 번의 반복에서 발생한 Watchers :"등의 의미에서 많은 지원 텍스트가 있지만이 텍스트의 대부분은 다양한 기능의 Javascript 코드입니다. 이 문제를 진단하기위한 경험 규칙이 있습니까? 항상 완화 할 수있는 문제입니까? 아니면이 문제를 경고로 취급해야 할 정도로 복잡한 응용 프로그램이 있습니까?
Ven가 말했듯이, 당신은 각 $digest
주기 마다 다른 (동일하지 않은) 객체를 반환 하거나 데이터를 너무 많이 변경하고 있습니다.
앱의 어느 부분이이 동작을 일으키는 지 알아내는 가장 빠른 솔루션은 다음과 같습니다.
- 모든 의심스러운 HTML 제거-기본적으로 템플릿에서 모든 HTML을 제거하고 경고가 없는지 확인합니다.
- 경고가없는 경우-제거한 html의 작은 부분을 추가하고 문제가 다시 발생하는지 확인하십시오.
- 경고를받을 때까지 2 단계를 반복합니다. 문제의 원인이되는 HTML 부분을 파악할 수 있습니다.
- 추가 조사-3 단계의 부품은
$scope
각$digest
주기 에서 개체를 변경 하거나 동일하지 않은 개체를 반환 합니다. $digest
1 단계 후에도 반복 경고 가 계속 발생하면 의심스러운 일을하고있을 것입니다. 상위 템플릿 / 범위 / 컨트롤러에 대해 동일한 단계를 반복합니다.
또한 사용자 정의 필터의 입력을 변경하지 않는지 확인하고 싶습니다.
JavaScript에는 일반적으로 예상하는 것처럼 작동하지 않는 특정 유형의 객체가 있습니다.
new Boolean(true) === new Boolean(true) // false
new Date(0) == new Date(0) // false
new String('a') == new String('a') // false
new Number(1) == new Number(1) // false
[] == [] // false
new Array == new Array // false
({})==({}) // false
일반적으로 매번 다른 개체를 반환 할 때 발생합니다.
예를 들어 다음에서 사용하는 경우 ng-repeat
:
$scope.getObj = function () {
return [{a: 1}, {b: 2}];
};
Angular가 "안정성"을 가지려고하고 동일한 결과를 2 번 반환 할 때까지 (와 비교하여 ===
) 함수를 실행하기 때문에이 오류 메시지가 표시됩니다.이 경우에는 함수가 항상 a 새 개체.
console.log({} === {}); // false. Those are two different objects!
이 경우 개체를 범위에 직접 저장하여 수정할 수 있습니다.
$scope.objData = [{a: 1}, {b: 2}];
$scope.getObj = function () {
return $scope.objData;
};
이렇게하면 항상 동일한 객체를 반환합니다!
console.log($scope.objData === $scope.objData); // true (a bit obvious...)
(복잡한 응용 프로그램에서도 이러한 문제가 발생해서는 안됩니다.)
업데이트 : Angular 는 웹 사이트에 좀 더 자세한 설명을 추가했습니다 .
이 솔루션을 여기에 던지고 싶었습니다. 다른 사람들에게 도움이되기를 바랍니다. 호출 될 때마다 새 개체를 만드는 생성 된 속성을 반복했기 때문에이 반복 문제가 발생했습니다.
처음 요청했을 때 생성 된 개체를 캐싱 한 다음 항상 캐시가있는 경우 반환하여 문제를 해결했습니다. 필요에 따라 캐시 된 결과를 파괴하는 dirty () 메서드도 추가되었습니다.
나는 다음과 같은 것을 가지고 있었다.
function MyObj() {
var myObj = this;
Object.defineProperty(myObj, "computedProperty" {
get: function () {
var retObj = {};
return retObj;
}
});
}
그리고 구현 된 솔루션은 다음과 같습니다.
function MyObj() {
var myObj = this,
_cached;
Object.defineProperty(myObj, "computedProperty" {
get: function () {
if ( !_cached ) {
_cached = {};
}
return _cached;
}
});
myObj.dirty = function () {
_cached = null;
}
}
나는 같은 문제가 있었다-나는 매번 새로운 날짜를 만들고 있었다. 그래서 날짜를 다루는 사람을 위해 다음과 같이 모든 호출을 변환했습니다.
var date = new Date(); // typeof returns object
에:
var date = new Date().getTime(); // typeof returns number
날짜 개체 대신 숫자를 초기화하면 문제가 해결되었습니다.
There also is the possibility of it not being an infinite loop at all. 10 iterations is not a sufficiently large number to conclude that with any amount of certainty. So before going on a wild-goose chase it may be advisable to rule out that possibility first.
The easiest method to do so is increasing the maximum digest loop count to a much larger number, which can be done in the module.config
method, using the $rootScopeProvider.digestTtl(limit)
method. If the infdig
error does no longer appear you simply have some sufficiently complex update logic.
If you build data or views relying on recursive watches you may want to search for iterative solutions (i.e. not relying on new digest loops to be started) using while
, for
or Array.forEach
. Sometimes the structure is just highly nested and not even recursive, there probably is not much to be done in those cases except raising the limit.
Another method of debugging the error is looking at the digest data. If you pretty print the JSON you get an array of arrays. Each top level entry represents an iteration, each iteration consists of a list of watch entries.
If you for example have a property which is modified in a $watch
on itself it is easy to see that the value is changing infinitely:
$scope.vm.value1 = true;
$scope.$watch("vm.value1", function(newValue)
{
$scope.vm.value1 = !newValue;
});
[
[
{
"msg":"vm.value1",
"newVal":true,
"oldVal":false
}
],
[
{
"msg":"vm.value1",
"newVal":false,
"oldVal":true
}
],
[
{
"msg":"vm.value1",
"newVal":true,
"oldVal":false
}
],
[
{
"msg":"vm.value1",
"newVal":false,
"oldVal":true
}
],
[
{
"msg":"vm.value1",
"newVal":true,
"oldVal":false
}
]
]
Of course in larger project this may not be as simple, especially since the msg
field often has the value "fn: regularInterceptedExpression"
if the watch is a {{ }}
interpolation.
Other than that the already mentioned methods, like cutting down the HTML to find the source of the problem, are of course helpful.
It's a known bug in ui-router
, this helped us: https://github.com/angular-ui/ui-router/issues/600
the easy way is : use angular.js,not the min file. open it and find the line:
if ((dirty || asyncQueue.length) && !(ttl--)) {
add line below:
console.log("aaaa",watch)
and then refresh your page, in the develope tools console,you will find you error code .
I would also like to mention that I received this error message when I had a typo in the templateUrl of a custom directive that I had in my project. Due to the typo, the template could not be loaded.
/* @ngInject */
function topNav() {
var directive = {
bindToController: true,
controller: TopNavController,
controllerAs: 'vm',
restrict: 'EA',
scope: {
'navline': '=',
'sign': '='
},
templateUrl: 'app/shared/layout/top-navTHIS-IS-A-TYPO.html'
};
Look in the network tab of your web browser's dev tools, and look to see if any resource is having a 404 error.
Easy to overlook, because the error message is very cryptic and seemingly unrelated to the real issue.
I was having this issue in my project because the .otherwise() was missing my route definition and I was hitting wrong route.
I had this issue because I was doing this
var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => {
return ve.rawMaterial.id = rawMaterial.id;
});
Instead of this: (notice = vs ===), my unit test started breaking and I found my stupidity
var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => {
return ve.rawMaterial.id === rawMaterial.id;
});
I ran into this issue where I needed a dynamic tooltip... it caused angular to recalculate it every time as a new value (even though it was the same). I created a function to cache the computed value like so:
$ctrl.myObj = {
Title: 'my title',
A: 'first part of dynamic toolip',
B: 'second part of dynamic tooltip',
C: 'some other value',
getTooltip: function () {
// cache the tooltip
var obj = this;
var tooltip = '<strong>A: </strong>' + obj.A + '<br><strong>B: </strong>' + obj.B;
var $tooltip = {
raw: tooltip,
trusted: $sce.trustAsHtml(tooltip)
};
if (!obj.$tooltip) obj.$tooltip = $tooltip;
else if (obj.$tooltip.raw !== tooltip) obj.$tooltip = $tooltip;
return obj.$tooltip;
}
};
Then in the html, I accessed it like this:
<input type="text" ng-model="$ctrl.myObj.C" uib-tooltip-html="$ctrl.myObj.getTooltip().trusted">
this is how I approached it and found a solution: I checked the text, it showed:
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [[{"msg":"statement === statment && functionCall()","newVal":[{"id":7287,"referen...
so if you can see the
msg
that's the statment generating the error. I checked the function called in this message, I returned (false) from all of them just to determine which one have the problem. one of them was calling a function that keeps changing the return, which is the problem.
As crazy as it sounds, I fixed this error just by restarting my browser when it just cropped up all of a sudden.
So one solution is to just clear your browser's cache or try restarting the browser.
'Programing' 카테고리의 다른 글
numpy에서 1D 배열을 2D 배열로 변환 (0) | 2020.09.12 |
---|---|
힙 크기보다 훨씬 많은 메모리를 사용하는 Java (또는 올바른 Docker 메모리 제한 크기) (0) | 2020.09.12 |
Swift를 사용한 하위 클래스 UIApplication (0) | 2020.09.12 |
JavaScript로 GetElementById 대신 getElementByClass를 사용하는 방법은 무엇입니까? (0) | 2020.09.12 |
Graph API를 사용하는 Facebook 'Friends.getAppUsers' (0) | 2020.09.12 |