调试$ digest已在进行中错误

时间:2015-05-01 18:40:26

标签: javascript angularjs hybrid-mobile-app fastclick.js

我正在构建一个复杂的混合应用程序并且已经在真实设备上进行测试。偶尔,我从Angular那里得到了可怕的$digest already in progress错误 - 特别是,它似乎是在一个有点长的消化周期之后。从堆栈跟踪看来,它似乎是从更新location.href的Angular defer函数启动的,然后触发fastclick以发送touchend,而touchend又触发导致错误的第二个摘要。有没有人遇到过同样的错误 - 如果有的话,你是怎么解决它的?

对于那些感兴趣的人,这是我在stacktrace中看到的:

Error: [$rootScope:inprog] $digest already in progress
http://errors.angularjs.org/1.3.0/$rootScope/inprog?p0=%24digest:
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:80:32
beginPhase@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:14473:31
$apply@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:14220:21
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:22523:29
eventHandler@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:3013:25
dispatchEvent@sendClick@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/fastclick/fastclick.js:295:30
onTouchEnd@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/fastclick/fastclick.js:589:18
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/fastclick/fastclick.js:105:43
url@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:5022:19
setBrowserUrlWithFallback@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:11080:21
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:11186:40
$eval@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:14123:28
$digest@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:13939:36
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:14161:33
completeOutstandingRequest@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:4877:15
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:5250:33

1 个答案:

答案 0 :(得分:4)

这是破坏者(source link):

   // other considerations:
   //
   // you might read 1 char at a time.  this can simplify
   //    your loop, possibly easier to debug
   //    ... would you have to detect and remove eoln?  i.e.  '\n'
   //    ... how would you handle a bad input 
   //        such as not hex char, odd char count in a line
   //
   // I would probably prefer to use getline(),
   //    it will read until eoln(), and discard the '\n'
   //    then in each string, loop char by char, creating char pairs, etc.
   //
   // Converting a vector<uint8_t> to char bytes[] can be an easier
   //    effort in some ways.  A vector<> guarantees that all the values
   //    contained are 'packed' back-to-back, and contiguous in
   //    memory, just right for binary stream output
   //
   //    vector.size() tells how many chars have been pushed
   //
   // NOTE: the formatted 'insert' operator ('<<') can not
   //       transfer binary data to a stream.  You must use
   //       stream::write() for binary output.
   //
   std::stringstream ssOut;

   // possible approach:
   // 1 step reinterpret_cast 
   // - a binary block output requires "const char*"

   const char* myBuff = reinterpret_cast<const char*>(&myBytes.front());

   ssOut.write(myBuff, myBytes.size()); 
   // block write puts binary info into stream

   // confirm
   std::cout << "\nConfirm6:  ";

   std::string s = ssOut.str();  // string with binary data

   for (size_t i=0; i<s.size(); ++i)
   {
      // because binary data is _not_ signed data, 
      // we need to 'cancel' the sign bit
      unsigned char ukar = static_cast<unsigned char>(s[i]); 

      // because formatted output would interpret some chars 
      //   (like null, or \n), we cast to int
      int  intVal = static_cast<int>(ukar);  

      // cast does not generate code

      // now the formatted 'insert' operator 
      // converts and displays what we want
      std::cout << std::hex << std::setw(2) << std::setfill('0') 
                << intVal << " ";
   }
   std::cout << std::endl;
   //
   //
   return (0);
} // int t194(void)

问题是人工FastClick.prototype.sendClick = function(targetElement, event) { // ... some lines skipped clickEvent = document.createEvent('MouseEvents'); clickEvent.forwardedTouchEvent = true; targetElement.dispatchEvent(clickEvent); // got you! }; 的处理程序将立即解雇demo)。这通常很好 - 但不适用于Angular,因为click事件已在touchEnd阶段内生成,而$digest似乎对其必须处理的事件有些乐观ng-click代码。因此$apply ka-boom。

无论如何,这件事似乎很容易解决:只是异步事件发送!一种相当直接的方法是用{...}替换$digest行。

got you!

至少在我们的案例中似乎有效。 )