$ प्रगति त्रुटि में पहले से ही लागू है


133

स्टैक ट्रेस:

Error: $apply already in progress
at Error (<anonymous>)
at beginPhase (file:///android_asset/www/built.min.js:7:22740)
at Object.Scope.$apply (file:///android_asset/www/built.min.js:7:25967)
at navigator.geolocation.getCurrentPosition.that (file:///android_asset/www/built.min.js:13:8670)
at Object.geolocation.getCurrentPosition (file:///android_asset/www/plugins/org.apache.cordova.core.geolocation/www/geolocation.js:122:13)
at Object.getCurrentPosition (file:///android_asset/www/built.min.js:13:8589)
at Object.getCurrentPosition (file:///android_asset/www/built.min.js:13:8277)
at Object.getCurrentCity (file:///android_asset/www/built.min.js:13:8941)
at Object.$scope.locateDevice (file:///android_asset/www/built.min.js:13:10480)
at file:///android_asset/www/built.min.js:7:12292:7

इस कोड को संदर्भित करता है http://pastebin.com/B9V6yvFu

    getCurrentPosition: cordovaReady(function (onSuccess, onError, options) {

        navigator.geolocation.getCurrentPosition(function () {
            var that = this,
                args = arguments;

            if (onSuccess) {
                $rootScope.$apply(function () {
                    onSuccess.apply(that, args);
                });
            }
        }, function () {
            var that = this,
                args = arguments;
            if (onError) {
                $rootScope.$apply(function () {
                    onError.apply(that, args);
                });
            }
        }, {
            enableHighAccuracy: true,
            timeout: 20000,
            maximumAge: 18000000
        });
    })

अजीब बात है, मेरे LG4X पर यह ठीक काम करता है, हालांकि मेरे सैमसंग s2 पर यह उपरोक्त त्रुटि फेंकता है। किसी भी विचार क्या गलत है?


1
क्या आपने stackoverflow.com/a/12859093/1266600 की कोशिश की है ? यह इसलिए हो सकता है क्योंकि विभिन्न उपकरण -> विभिन्न प्रसंस्करण गति -> अलग-अलग समय, जो कुछ स्थानों पर टकराव का कारण बन सकते हैं, लेकिन अन्य नहीं।
सुषैने97

20
उपयोग$timeout()
ओनुर येल्ड्रिम

7
+1 से $ टाइमआउट () टिप्पणी। देखें: stackoverflow.com/questions/12729122/…
ट्रेवर

जवाबों:


106

आपको यह त्रुटि इसलिए मिल रही है क्योंकि आप $applyकिसी मौजूदा पाचन चक्र के अंदर कॉल कर रहे हैं ।

बड़ा सवाल यह है: आप क्यों बुला रहे हैं $apply? $applyजब तक आप एक गैर-कोणीय घटना से हस्तक्षेप नहीं कर रहे हैं तब तक आपको कभी भी कॉल करने की आवश्यकता नहीं होनी चाहिए । $applyआमतौर पर अस्तित्व का मतलब है कि मैं कुछ गलत कर रहा हूं (जब तक, फिर से, $ लागू नॉन-एंगुलर घटना से नहीं होता है)।

यदि $applyवास्तव में यहां उपयुक्त है, तो "सुरक्षित आवेदन" दृष्टिकोण का उपयोग करने पर विचार करें:

https://coderwall.com/p/ngisma


41
लिंक्ड सेफ अप्लाई का मुख्य एक एंटी-पैटर्न (डॉक्स के अनुसार) github.com/angular/angular.js/wiki/Anti-Patterns है । यदि आप भविष्य-समर्थित ($$ चरण दूर जा रहे हैं!) इसे करने का तरीका, बिना समय निर्धारित किए अपने कोड को $ timeout () में लपेटें। यह वर्तमान पाचन चक्र पूरा होने के बाद सुरक्षित रूप से लागू होगा।
बीटॉर्बस्ट

@ बबोरबस्ट सहमत। सुरक्षित आवेदन खराब है। इसके अलावा, कई बार कॉलिंग लागू करने से संपूर्ण समस्याएँ हो सकती हैं। सभी को एक साथ समस्या से बचने के लिए कोड की संरचना करना सबसे अच्छा है।
ब्रायन जेनिसियो

im कॉलिंग अप्लाई नहीं
सर्किट्री


41

आप इस कथन का उपयोग कर सकते हैं:

if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
    $scope.$apply();
}

1
यह चर का उपयोग करने के लिए अनुशंसित नहीं है जो $ $ से शुरू होते हैं क्योंकि वे निजी हैं। इस मामले में $ $ चरण
आरा येरेशियन

9
यह उत्तर ऊपर वाले की तुलना में बहुत अधिक उपयोगी है। मुझे एक समाधान की आवश्यकता है, न कि किसी ऐसी चीज के लिए जिसे मेरे नियंत्रण से परे हो। हमारे पास कोणीय और विरासत कोड का मिश्रण है, और उन्हें किसी तरह बातचीत करनी है। यह केवल सभी विरासत कोड को फिर से लिखना महंगा है ...
जॉर्डन लैप

24

यदि कुछ मामलों में गुंजाइश लागू की जानी चाहिए, तो आप एक टाइमआउट सेट कर सकते हैं ताकि अगले टिक तक $ लागू स्थगित हो जाए

setTimeout(function(){ scope.$apply(); });

या एक $ टाइमआउट (फ़ंक्शन () {..}) में अपना कोड लपेटें; क्योंकि यह स्वचालित रूप से $ निष्पादन के अंत में गुंजाइश को लागू करेगा। यदि आपको अपने कार्य को समकालिक व्यवहार करने की आवश्यकता है, तो मैं पहला काम करूंगा।


मैंने पाया कि मुझे setTimeout(function() { $apply(function() {... do stuff ...} ) })नीचे @Tamil Vendhan के भीतर कार्रवाई को शामिल करने की आवश्यकता है ।
प्रोटोटाइप

6
सेटटाइमआउट का उपयोग न करें, जो बस एक और $ लागू होने की आवश्यकता पैदा करता है। फ्रेमवर्क का उपयोग करें, इसकी एक $ टाइमआउट सेवा है जो आपके लिए यह सब करती है।
स्पेंसर

10

मेरे मामले में मैं $applyकुछ घटना को जोड़ने के लिए कोणीय कैलेंडर UI के साथ उपयोग करता हूं :

$scope.eventClick = function(event){           
    $scope.$apply( function() {
        $location.path('/event/' + event.id);
    });
};

समस्या के दस्तावेज़ को पढ़ने के बाद: https://docs.angularjs.org/error/ $ rootScope / inprog

अविभाज्य एपीआई (सिंक / Async) हिस्सा बहुत दिलचस्प है:

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

चूंकि, MyController कंस्ट्रक्टर हमेशा एक $ लागू कॉल के भीतर से त्वरित होता है, हमारा हैंडलर एक से एक नए $ लागू ब्लॉक में प्रवेश करने की कोशिश कर रहा है।

मैं कोड को इसमें बदलता हूं:

$scope.eventClick = function(event){           
    $timeout(function() {
        $location.path('/event/' + event.id);
    }, 0);
};

एक जादू की तरह काम करता है !

यहां हमने भविष्य में कॉल स्टैक में स्कोप में परिवर्तन को शेड्यूल करने के लिए $ समय का उपयोग किया है। 0ms का टाइमआउट प्रदान करने से, यह जल्द से जल्द होगा और $ टाइमआउट यह सुनिश्चित करेगा कि कोड को एक एकल $ लागू ब्लॉक में बुलाया जाएगा।


1
आपके $ समय समाप्ति की देरी 0 समाधान बहुत बढ़िया है।
अहसान

9

कोणीय 1.3 में, मुझे लगता है, उन्होंने एक नया कार्य जोड़ा - $scope.$applyAsync()। यह फ़ंक्शन कॉल बाद में लागू होता है - वे कम से कम 10 एमएस के बारे में बाद में कहते हैं। यह सही नहीं है, लेकिन यह कम से कम कष्टप्रद त्रुटि को खत्म करता है।

https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope # $ applyAsync


3

किसी भी समय, प्रगति में केवल एक $digestया $applyऑपरेशन हो सकता है । यह आपके आवेदन में प्रवेश करने से कीड़े का पता लगाने के लिए बहुत कठिन है। इस त्रुटि का स्टैक ट्रेस आपको वर्तमान में निष्पादित $applyया $digestकॉल की उत्पत्ति का पता लगाने की अनुमति देता है , जो त्रुटि का कारण बना।

अधिक जानकारी: https://docs.angularjs.org/error/$rootScope/inprog?p0=>&ly


2

बस इस मुद्दे को हल कर दिया। इसका दस्तावेज यहां दिया गया है

मैं $rootScope.$applyएक ही प्रवाह में दो बार फोन कर रहा था । मैंने जो भी किया वह सेवा फ़ंक्शन की सामग्री के साथ लिपटा है setTimeout(func, 1)


1

मुझे पता है कि यह पुराना सवाल है, लेकिन अगर आपको वास्तव में $ गुंजाइश का उपयोग करने की आवश्यकता है। $ applyAsync ();


0

मैं $ स्कोप कहता हूं। एक बार में कई कॉल को नजरअंदाज करने के लिए $ इस तरह लागू होता है।

      var callApplyTimeout = null;
      function callApply(callback) {
          if (!callback) callback = function () { };
          if (callApplyTimeout) $timeout.cancel(callApplyTimeout);

          callApplyTimeout = $timeout(function () {
              callback();
              $scope.$apply();
              var d = new Date();
              var m = d.getMilliseconds();
              console.log('$scope.$apply(); call ' + d.toString() + ' ' + m);
          }, 300);
      }

बस फोन करो

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