कोणीय "10 $ डाइजेस्ट () पुनरावृत्तियों तक कैसे पहुंचा" त्रुटि का निवारण


91

10 $ डाइजेस्ट () पुनरावृत्तियों तक पहुंच गया। निरस्त किया जा रहा!

"अंतिम 5 पुनरावृत्तियों में देखे गए वॉचर्स:", आदि के अर्थ में बहुत से सहायक पाठ हैं, लेकिन इस पाठ का एक बहुत विभिन्न कार्यों से जावास्क्रिप्ट कोड है। क्या इस समस्या के निदान के लिए अंगूठे के नियम हैं? क्या यह एक समस्या है जिसे हमेशा के लिए कम किया जा सकता है, या क्या ऐसे अनुप्रयोग जटिल हैं जो इस समस्या को सिर्फ एक चेतावनी के रूप में माना जाना चाहिए?

जवाबों:


80

जैसा कि वेन ने कहा, आप या तो प्रत्येक $digestचक्र पर अलग (समान नहीं) ऑब्जेक्ट लौटा रहे हैं , या आप डेटा को कई बार बदल रहे हैं।

सबसे तेज़ समाधान यह पता लगाने के लिए कि आपके ऐप का कौन सा हिस्सा इस व्यवहार का कारण बन रहा है:

  1. सभी संदिग्ध HTML हटाएं - मूल रूप से अपने सभी HTML को टेम्पलेट से हटा दें, और जांचें कि क्या कोई चेतावनी नहीं है
  2. अगर कोई चेतावनी नहीं है - आपके द्वारा हटाए गए html के छोटे हिस्सों को जोड़ें और जांचें कि क्या समस्या वापस आ गई है
  3. चरण 2 को दोहराएं जब तक आपको चेतावनी नहीं मिलती - आप यह पता लगाएंगे कि आपके HTML का कौन सा हिस्सा समस्या के लिए जिम्मेदार है
  4. आगे की जाँच करें - चरण 3 से भाग या तो वस्तुओं को उत्परिवर्तित करने के लिए जिम्मेदार है या $scopeप्रत्येक पर गैर-समान वस्तुओं को वापस कर रहा है$digest चक्र ।
  5. यदि आपके पास अभी भी $digestचरण 1 के बाद पुनरावृति चेतावनी है, तो आप शायद कुछ बहुत ही संदिग्ध कर रहे हैं। पैरेंट टेम्पलेट / स्कोप / कंट्रोलर के लिए समान चरणों को दोहराएं

आप यह भी सुनिश्चित करना चाहते हैं कि आप अपने कस्टम फ़िल्टर के इनपुट को बदल नहीं रहे हैं

ध्यान रखें, कि जावास्क्रिप्ट में विशिष्ट प्रकार की वस्तुएं होती हैं जो आपके साथ वैसा व्यवहार नहीं करती हैं जैसी आप आमतौर पर उम्मीद करते हैं:

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

5
धन्यवाद! यह एक सहायक विधर्मी है। मैं यह भी सोच रहा हूं कि एनग्रेपेट के लिए एंगुलर के नए "ट्रैक बाय" फीचर से मुझे भी मदद मिलेगी। मैं एक सेवा में अंडरस्कोर का उपयोग करके कुछ मानचित्र () और groupBy () सामान कर रहा हूं, इसलिए यह निश्चित रूप से हर बार "अलग" ऑब्जेक्ट लौटा रहा है (भले ही वे तार्किक रूप से समान चीजों का प्रतिनिधित्व करते हैं - "ट्रैक बाय आईडी" से कोणीय को देखने में मदद नहीं मिलेगी। "परिवर्तन" के रूप में यदि वे वास्तव में नहीं हैं)।
विस्फ़ोटक

2
यदि आप ऐसा कर रहे हैं map()और groupBy()यह सुनिश्चित करने की अपेक्षा कर रहे हैं कि आपके $watches ने docs.angularjs.org/api/ng.$rootScope.Scope#$watchobjectEquality $watch('myFunctionDoingGropby',callback,true)
g00fy

ऊपर की टिप्पणी के अनुसार, "ट्रैक द्वारा" मेरा मुद्दा तय किया गया (यहां दस्तावेज़ देखें: docs.angularjs.org/api/ng/directive/ngRepeat )। मैं एक व्याख्यात्मक टिप्पणी के लिए आभारी हूँ जो यह बताता है कि यह क्यों काम करता है ...
सोफिरियो

@ g00fy: यह एक अच्छा नेतृत्व था, और मैं अपनी सूची पुनर्प्राप्ति फ़ंक्शन को मेरे चर पर एक चर के साथ बदलने में सक्षम था, $scopeजिसे _.mapएक बार -ed सूची सौंपी जाती है - लेकिन सामान्य मामले में, आप कैसे कहेंगे कि वस्तु समानता द्वारा गंदी जाँच को प्रभावित करेगा यदि यह एक मैन्युअल रूप से बनाई गई है $watchकि ट्रिपिंग है, लेकिन ngRepeat?
या मैपर

73

आमतौर पर ऐसा तब होता है जब आप हर बार एक अलग वस्तु लौटा रहे होते हैं।

उदाहरण के लिए, यदि आप इसमें उपयोग करते हैं ng-repeat:

$scope.getObj = function () {
  return [{a: 1}, {b: 2}];
};

आप इस त्रुटि संदेश को प्राप्त करने जा रहे हैं क्योंकि कोणीय "स्थिरता" रखने की कोशिश करता है और फ़ंक्शन को तब तक निष्पादित करेगा जब तक कि एक ही परिणाम 2 बार (तुलना के साथ ===) वापस नहीं आता है, जो हमारे मामले में कभी भी सही नहीं होगा क्योंकि फ़ंक्शन हमेशा एक रिटर्न देता है नई वस्तु।

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

(आपको कभी भी जटिल अनुप्रयोगों पर भी मुठभेड़ नहीं करनी चाहिए)।

अद्यतन: कोणीय ने अपनी वेबसाइट पर कुछ और अधिक गहराई से स्पष्टीकरण जोड़ा है


आप इसे होने से कैसे रोकेंगे? मैं अभी ऐसी ही स्थिति बना रहा हूं।
विजेता

2
सुनिश्चित करें कि आप प्रत्येक कॉल पर अलग-अलग ऑब्जेक्ट नहीं बना रहे हैं;)।
शुक्र

मैं यह कैसे सुनिश्चित कर सकता हूं? मैं फंक (obj) में आइटम की तरह कुछ कर रहा हूं, लेकिन फंक को एक बार के बजाय कई बार कहा जाता है जैसे मैं आशा करता हूं। मैंने फंक को कॉल करने के लिए एनजी-इनिट का उपयोग करने की कोशिश की और फिर इसे एक मॉडल के दायरे में संलग्न किया, लेकिन यह भी काम नहीं किया।
विजेता

1
यह वह उदाहरण है जिसे आप इस समस्या पर हर जगह देखते हैं। यह बहुत भयानक होगा यदि कोणीय आपत्तिजनक कार्य को इंगित कर सकता है, जो यह व्यवहार करता है ...
Jorn

1
@BenWheeler यह निश्चित रूप से 2013 के बाद से सुधार हुआ है, हाँ: P।
Ven

11

बस इस समाधान को यहां फेंकना चाहता था, उम्मीद है कि यह दूसरों की मदद करेगा। मुझे यह पुनरावृत्ति समस्या हो रही थी क्योंकि मैं एक उत्पन्न संपत्ति पर ध्यान केंद्रित कर रहा था जो कि हर बार एक नई वस्तु बना रही थी जिसे यह कहा जाता था।

मैंने इसे पहली बार अनुरोध किए जाने पर उत्पन्न ऑब्जेक्ट को कैशिंग करके तय किया, और अगर यह मौजूद था तो हमेशा कैश वापस करना। एक गंदा () तरीका भी जोड़ा गया, जो आवश्यकतानुसार कैश्ड परिणामों को नष्ट कर देगा।

मेरे पास कुछ ऐसा था:

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

हे भगवान मैं चाहता हूं कि मैं तुम्हें 10 वर दे सकूं। आपने सिर्फ एक समस्या का हल किया, जिसने मुझे लगभग 3 घंटे तक दीवार के खिलाफ अपना सिर पीटा था। मैं तुमसे प्यार करता हूँ!
जीएमए

7

वहाँ भी यह एक अनंत लूप नहीं होने की संभावना है। 10 पुनरावृत्तियों को निष्कर्ष निकालने के लिए एक पर्याप्त बड़ी संख्या नहीं है कि किसी भी राशि की निश्चितता के साथ। तो एक जंगली-हंस पीछा करने से पहले उस संभावना को पहले खारिज करना उचित हो सकता है।

ऐसा करने का सबसे आसान तरीका अधिकतम पाचन लूप काउंट को बहुत बड़ी संख्या में बढ़ा रहा है, जो module.configविधि का उपयोग करके विधि में किया जा सकता है $rootScopeProvider.digestTtl(limit)। यदि infdigत्रुटि दिखाई नहीं देती है तो आपके पास बस कुछ पर्याप्त जटिल अपडेट लॉजिक है।

यदि आप पुनरावर्ती घड़ियों पर निर्भर होने वाले डेटा या विचारों का निर्माण करते हैं, तो आप पुनरावृत्त समाधानों की खोज करना चाहते हैं (अर्थात नए डाइजेस्ट लूप्स पर निर्भर न हो) का उपयोग करना while, forया Array.forEach। कभी-कभी संरचना केवल अत्यधिक नेस्टेड होती है और पुनरावर्ती भी नहीं होती है, सीमा को बढ़ाने के अलावा शायद उन मामलों में बहुत कुछ नहीं किया जाता है।

त्रुटि को डीबग करने का एक अन्य तरीका पाचन डेटा देख रहा है। यदि आप JSON को बहुत प्रिंट करते हैं तो आपको एरे की एक सरणी मिलती है। प्रत्येक शीर्ष स्तर प्रविष्टि एक पुनरावृत्ति का प्रतिनिधित्व करती है, प्रत्येक पुनरावृत्ति में घड़ी प्रविष्टियों की सूची होती है।

यदि आपके पास उदाहरण के लिए एक संपत्ति है जो अपने आप में संशोधित है, तो $watchयह देखना आसान है कि मूल्य असीम रूप से बदल रहा है:

$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
      }
   ]
]

बेशक बड़ी परियोजना में यह उतना सरल नहीं हो सकता है, खासकर जब से msgक्षेत्र में अक्सर मूल्य होता है "fn: regularInterceptedExpression"अगर घड़ी एक है{{ }} प्रक्षेप है।

समस्या के स्रोत का पता लगाने के लिए HTML को काटने जैसे अन्य पहले से बताए गए तरीके निश्चित रूप से सहायक हैं।


6

मुझे भी यही समस्या थी - मैं हर बार एक नई तारीख बना रहा था। इसलिए तारीखों से निपटने वाले किसी व्यक्ति के लिए मैंने इस तरह से सभी कॉलों को बदल दिया:

var date = new Date(); // typeof returns object

सेवा:

var date = new Date().getTime(); // typeof returns number

दिनांक ऑब्जेक्ट के बजाय किसी संख्या को प्रारंभ करना मेरे लिए इसे हल करता है।


2

आसान तरीका है: कोणीय फ़ाइल का उपयोग करें, न कि न्यूनतम फ़ाइल। इसे खोलें और लाइन खोजें:

if ((dirty || asyncQueue.length) && !(ttl--)) {

नीचे पंक्ति जोड़ें:

console.log("aaaa",watch)

और फिर अपने पेज को रीफ़्रेश करें, डेवलप टूल कंसोल में, आपको त्रुटि कोड मिलेगा।


1

यह एक ज्ञात बग है ui-router, इससे हमें मदद मिली: https://github.com/angular-ui/ui-router/issues/600


इससे मुझे काफी मदद मिली! आपको निश्चित रूप से इस पर विस्तार करना चाहिए और उस कोड को जोड़ना चाहिए जो समस्या को हल करता है, जो इस उत्तर पर है: github.com/angular-ui/ui-router/issues/…
लुलु

0

मैं यह भी उल्लेख करना चाहूंगा कि मुझे यह त्रुटि संदेश तब मिला जब मेरे पास एक कस्टम निर्देश के टेम्प्लेट यूआरएल में एक टाइपो था जो मैंने अपनी परियोजना में लिया था। टाइपो के कारण, टेम्प्लेट लोड नहीं किया जा सका।

/* @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'
    };

अपने वेब ब्राउज़र के उपकरण के नेटवर्क टैब में देखें, और देखें कि क्या किसी संसाधन में 404 त्रुटि है।

अनदेखी करना आसान है, क्योंकि त्रुटि संदेश बहुत ही गूढ़ है और वास्तविक मुद्दे से असंबंधित है।


0

मैं अपने प्रोजेक्ट में इस समस्या को ले रहा था क्योंकि .otherwise () मेरी रूट परिभाषा याद कर रहा था और मैं गलत रूट मार रहा था।


0

मेरे पास यह मुद्दा था क्योंकि मैं यह कर रहा था

var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => {
               return ve.rawMaterial.id = rawMaterial.id;
});

इसके बजाय: (नोटिस = बनाम ===), मेरी यूनिट का परीक्षण टूटने लगा और मुझे अपनी मूर्खता का पता चला

var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => {
               return ve.rawMaterial.id === rawMaterial.id;
});

0

मैं इस मुद्दे पर भाग गया, जहां मुझे एक गतिशील टूलटिप की आवश्यकता थी ... यह एक नए मूल्य (भले ही यह समान था) के रूप में इसे हर बार पुनर्गणना का कारण बना। मैंने गणनात्मक मूल्य को इस तरह कैश करने के लिए एक फ़ंक्शन बनाया:

$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;
    }
};

फिर html में, मैंने इसे इस तरह एक्सेस किया:

<input type="text" ng-model="$ctrl.myObj.C" uib-tooltip-html="$ctrl.myObj.getTooltip().trusted">

0

मैंने इसे देखा और इसका समाधान पाया: मैंने पाठ की जाँच की, यह दिखाया गया है:

Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

वॉचर्स ने अंतिम 5 पुनरावृत्तियों में निकाल दिया: [[{"msg": "statement === स्टेटमेंट और& functionCall ()", "newVal": [{"id": 7287, "referen ...

तो अगर आप देख सकते हैं

संदेश

यह त्रुटि पैदा करने वाली प्रतिमा है। मैंने इस संदेश में कहे गए फंक्शन को चेक किया, मैं उन सभी से वापस (गलत) आया जो यह निर्धारित करता है कि किसी को समस्या है। उनमें से एक एक फ़ंक्शन को कॉल कर रहा था जो रिटर्न को बदलता रहता है, जो कि समस्या है।


-3

जैसा कि यह लगता है कि पागल है, मैंने अपने ब्राउज़र को फिर से शुरू करके यह त्रुटि ठीक कर दी है जब यह अचानक समाप्त हो गया।

तो एक उपाय यह है कि आप अपने ब्राउज़र के कैश को साफ़ करें या ब्राउज़र को पुनः आरंभ करने का प्रयास करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.